iOS7中在UINavigationBar上添加UISearchBar时未显示取消按钮

22

我在UINavigationBar上方添加了UISearchBar,并将UISearchBar的showsCancelButton属性设置为YES,在iOS6中工作正常,但在iOS7中不显示取消按钮。我使用了以下代码片段:

UISearchBar *searchBar = [[UISearchBar alloc] initWithFrame:CGRectMake(0, 0, 600, 44)];
searchBar.showsCancelButton = YES;
searchBar.translucent = NO;
[searchBar setTintColor:[UIColor redColor]];
searchBar.backgroundColor = [UIColor yellowColor];
[self.navigationController.navigationBar   addSubview:searchBar];
7个回答

44

由于某些原因,在将UISearchBar添加到导航栏时,iOS 7不会显示取消按钮。如果您尝试将其设置为navigationItem的titleView,也会出现这种情况。

您可以通过先将UISearchBar包装在另一个UIView中来解决此问题。以下是我如何将其作为titleView执行:

UISearchBar *searchBar = [UISearchBar new];
searchBar.showsCancelButton = YES;
[searchBar sizeToFit];
UIView *barWrapper = [[UIView alloc]initWithFrame:searchBar.bounds];
[barWrapper addSubview:searchBar];
self.navigationItem.titleView = barWrapper;

我遇到了同样的问题并尝试了你的解决方案。然而,搜索栏使用了不同的样式,大小也不正确。你是否进一步改进了这个解决方案并修复了细节? - Codo
在将UISearchBar放置在UINavigationBar中之前,先将其包装在UIView中对我很有效。然而,我将其添加为子视图而不是titleView。 - Stephen
2
确实,搜索栏的样式发生了变化,与导航栏不太匹配。我使用了searchBar.searchBarStyle = UISearchBarStyleMinimal,这至少符合我的需求。 - Rodskjegg
对我来说,它似乎可以工作,除了我根本看不到搜索栏。如果我点击那个区域,键盘和搜索结果都能正常显示,但我看不到我正在输入的任何内容。 - Ken Koch
如果您的应用程序支持纵向和横向模式,那么当您切换方向时,它将无法正确地重新计算大小。这就是自动布局会有所帮助的地方,但这需要对titleView属性进行一些调整,以便在设置项目时自动调整大小。真是太烦人了。最终我只是创建了自己的取消按钮,并将其放置在rightBarButtonItem上。 - ArtSabintsev
被接受的答案是一个不错的开始,但正如人们所说,它会破坏样式和外观。@Rodskjegg的样式行加上将搜索栏包装在作为子视图添加到导航栏的uiview中对我很有帮助。 - skinsfan00atg

6

我曾遇到类似的问题,在iPhone上,搜索栏和取消按钮都显示正常,但在iPad上,取消按钮并未显示。将UIsearchBar包装到UIView中会出现样式问题,而在iPad上,可以将UIsearchBar设置为navigationItem的titleView,并添加UIBarButtonItem作为UIBarButtonSystemItemCancel来设置setRighttBarButtonItem。

    [self.navigationItem setLeftBarButtonItem:Nil animated:YES];
    self.navigationItem.titleView = self.searchBar;

    if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad) 
    {
        UIBarButtonItem *cancelButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCancel target:self action:@selector(searchBarCancelButtonClicked:)];

        [self.navigationItem setRightBarButtonItem: cancelButton animated:YES];
    }
    else {
        [self.navigationItem setRightBarButtonItem: nil animated:YES];
    }

我也遇到了一些样式问题(搜索栏最初太大,在界面旋转时无法正确调整大小),通过自己添加一个工具栏按钮解决了这个问题...虽然不是最干净的方法,但还是谢谢你的答案。 - Sebastian Boldt
这是我认为最不破坏原有结构的解决方案。相较于上述的 addSubview 方法,它在没有任何突兀的框架/动画问题的情况下对我更有效。非常好的解决方案! - manderson

4

是的,在iOS 7中,按钮位于屏幕上,但它的标题可能是不可见的。

我的解决方案是将搜索样式设置为“Minimal”,并在IB中选择“取消”文本颜色的工具栏色调颜色。

enter image description here

模拟器中的结果如下:

enter image description here


4

自从iOS 7开始,您只需在UISearchDisplayController上设置属性displaysSearchBarInNavigationBarYES,即可自动在导航栏中获得一个UISearchbar


3
如果没有使用搜索显示控制器呢? - Léo Natan
没错。我只想把搜索栏放在导航项内部。 - Steve
完全没有看到iOS8的弃用。 - czeluff
2
UISearchDisplayController在iOS 8中已被弃用...现在应该使用UISearchController。 - Herz Rod
如果您不需要同时支持iOS 7和8 - fabb

3
我遇到了同样的问题,这是我的解决方案,希望能对您有所帮助。
进一步解释如下: 我发现只需将 setShowsCancelButton:animated: 发送到 searchBar 中,它就像魔法一样起作用。 将 searchBar 添加到导航栏中最干净的方法是 self.navigationItem.titleView = self.searchBar; 调用 setShowsCancelButton:animated: 的适当时间是在 searchBarTextDidBeginEditing:searchBarTextDidEndEditing: 委托方法中,所以请记得将 self 设置为 searchBar 的代理。
- (void)viewDidLoad
{
    self.navigationItem.titleView = self.searchBar;
}

- (void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar
{
    [searchBar setShowsCancelButton:YES animated:YES]; 
}

- (void)searchBarTextDidEndEditing:(UISearchBar *)searchBar
{
    [searchBar setShowsCancelButton:NO animated:YES];
}

1
仅仅给出代码的答案通常在 SO 社区被看作不好的行为。你应该尝试添加一些关于您的代码如何工作或为什么要这样写的解释。 - codeMagic
2
回答已编辑以提供更多解释,我认为代码本身已经很容易理解了,请不要对我太苛刻,谢谢。 - 廖維平
1
我没有对你苛刻。作为你在SO上的第一个回答,我只是评论说解释会让回答更好。这对你和许多其他人来说可能很显而易见,但对将来遇到同样问题的某些人来说可能并非如此。 - codeMagic

2
我有同样的问题,在iPhone上搜索取消按钮显示正常,但在iPad上未能显示。
将UISearchBar包装在另一个UIView中的解决方法对我来说并不好用,因为它外观不同,在旋转时宽度也不正确。
我的解决方案很简单-使用没有取消按钮的搜索,并将取消按钮添加为UIBarButtonItem。

0

实现搜索栏代理并使用以下代码:

- (void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar
{
    searchBar.showsCancelButton = YES;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接