iOS:在导航栏中显示搜索栏时隐藏范围栏
Posted
技术标签:
【中文标题】iOS:在导航栏中显示搜索栏时隐藏范围栏【英文标题】:iOS: Scope bar hidden when search bar is displayed in navigation bar 【发布时间】:2014-12-29 22:39:40 【问题描述】:我正在尝试获取一个搜索栏,它是导航栏中的范围,就像视图首次出现的方式一样。如果您只是将 UISearchBar 拖到界面构建器中的表格视图控制器上,它就会像标题单元格一样放置在您的表格中。然后,当你点击它时,它会动画成我在下面的阵型。问题是我希望它以这种方式开始而无需任何点击,左侧有一个后退按钮,右侧没有取消按钮:
因此,为了在不点击的情况下立即获得搜索栏的焦点,我尝试在 viewDidLoad 中添加 [_searchBar becomeFirstResponder];
,但这不起作用。接下来我尝试了:
self.searchDisplayController.displaysSearchBarInNavigationBar = YES;
搜索栏确实会显示在导航栏中,但范围栏不见了,(WHY APPLE WHY)并且有一个尴尬的差距。
我也尝试过继承 UINavigationBar 并使其更高。更改它的大小很容易,但内容在栏的底部对齐,并与您尝试添加的任何内容重叠。
所以要重新迭代,当视图首次出现时,我需要在导航栏中显示搜索栏并带有范围控件,而无需用户点击。我还应该指定这是在 UITableViewController 上(因为页面有一个 UIRefreshConrol),所以简单地将工具栏放在表格视图上方不是一个选项。谢谢。
【问题讨论】:
【参考方案1】:tl;dr: 不要。
您应该知道,将UISearchBar
添加到UITableView
的headerView
会调用UIKit
中的一些自定义代码,这有助于在启动时隐藏范围栏。虽然在 ios 6 及更早版本中一直显示范围栏更容易,但 iOS 7 改变了这一点。
您的第一种方法,在viewDidLoad
中使用becomeFirstResponder
是一个好主意,但是在视图加载到内存后(例如从NIB 加载)调用此方法。该视图尚未添加到视图层次结构中,因此它不能成为第一响应者。 viewDidAppear:
在视图加载到视图层次结构之后被调用,becomeFirstResponder
实际上允许UISearchBar
接收焦点。
范围栏本身是UISearchBar
的隐藏(默认)子视图。从技术上讲,您可以循环浏览子视图并将其设置为不隐藏:
- (void)viewDidLoad
[super viewDidLoad];
[self recurseSubviewsForView:self.searchDisplayController.searchBar];
- (void)recurseSubviewsForView:(UIView *)view
for (UIView *subview in view.subviews)
if ((CGRectGetMinY(subview.frame) == CGRectGetMaxY(self.searchDisplayController.searchBar.frame)) && subview.hidden)
subview.hidden = NO;
self.searchDisplayController.searchBar.showsScopeBar = YES;
[self.searchDisplayController.searchBar sizeToFit];
[self recurseSubviewsForView:subview];
这通常是个坏主意。有一个基本的检查来查看被定位的子视图是包含范围栏的子视图,但这可能会中断,可能不向后兼容,等等。
您必须问自己的真正问题是为什么我希望范围栏始终可见?它现在的工作方式是,当用户点击搜索字段时,范围栏将显示动画,并在搜索字段不再具有焦点时隐藏自身。即使使用上面的“hack”,只要用户点击范围按钮,搜索栏就会获得焦点。当搜索甚至不活动时显示搜索选项有什么意义?如有疑问,请求助于 Apple 的建议。从长远来看,这将使您的生活更轻松,并可能使您的应用外观和行为更好。苹果并不是一时兴起才添加这种交互的。他们疯狂地测试它。这就是为什么很难让它以另一种方式工作。这就是为什么当 UISearchBar
是 UITableView
的 headerView
时运行特殊代码的原因......因为它可能对用户更好。
此外,我看到您针对 iOS 8 的屏幕截图,但您的代码截图显示使用 UISearchDisplayController
。此范例已被弃用,取而代之的是 UISearchController
。请考虑更新。
【讨论】:
很沮丧,我没想过将becomeFirstResponder
放入viewDidAppear:
。谢谢!回答您的问题:我希望它始终可见,因为 VC 专门用于搜索。 (查看 Instagram 的搜索选项卡 - 这就是我所追求的)此外,使用 UISearchDisplayController
有一个很好的理由 - 与 iOS7 兼容。它可能在 iOS8 中已被弃用,但它仍然完全有效(并且仍在 IB 的对象库中)。剩下的问题:如果您使用在导航栏中显示搜索栏的选项,为什么Apple会隐藏范围而不考虑设置showsScope = YES
?
为什么会隐藏范围栏?我不知道,但是it is documented。 “如果您在导航栏中显示的搜索栏中将showsScopeBar
属性设置为YES
,系统将引发异常。” 可能是因为导航栏高度不能高到无法显示范围栏。以上是关于iOS:在导航栏中显示搜索栏时隐藏范围栏的主要内容,如果未能解决你的问题,请参考以下文章
当我在小于 10 的 ios 版本中隐藏/显示导航栏时,应用程序在进入后台后卡住