【问题标题】:iOS: Scope bar hidden when search bar is displayed in navigation bariOS:在导航栏中显示搜索栏时隐藏范围栏
【发布时间】:2014-12-29 22:39:40
【问题描述】:

我正在尝试获取一个搜索栏,它是导航栏中的范围,就像视图首次出现的方式一样。如果您只是将 UISearchBar 拖到界面构建器中的表格视图控制器上,它就会像标题单元格一样放置在您的表格中。然后,当你点击它时,它会动画成我在下面的阵型。问题是我希望它以这种方式开始而无需任何点击,左侧有一个后退按钮,右侧没有取消按钮:

因此,为了在不点击的情况下立即获得搜索栏的焦点,我尝试在 viewDidLoad 中添加 [_searchBar becomeFirstResponder];,但这不起作用。接下来我尝试了:

self.searchDisplayController.displaysSearchBarInNavigationBar = YES;

搜索栏确实会显示在导航栏中,但范围栏不见了,(WHY APPLE WHY)并且有一个尴尬的差距。

我也尝试过继承 UINavigationBar 并使其更高。更改它的大小很容易,但内容在栏的底部对齐,并与您尝试添加的任何内容重叠。

所以要重新迭代,当视图首次出现时,我需要在导航栏中显示搜索栏并带有范围控件,而无需用户点击。我还应该指定这是在 UITableViewController 上(因为页面有一个 UIRefreshConrol),所以简单地将工具栏放在表格视图上方不是一个选项。谢谢。

【问题讨论】:

    标签: ios iphone


    【解决方案1】:

    tl;dr: 不要。

    您应该知道,将UISearchBar 添加到UITableViewheaderView 会调用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 的建议。从长远来看,这将使您的生活更轻松,并可能使您的应用外观和行为更好。苹果并不是一时兴起才添加这种交互的。他们疯狂地测试它。这就是为什么很难让它以另一种方式工作。这就是为什么当 UISearchBarUITableViewheaderView 时运行特殊代码的原因......因为它可能对用户更好。

    此外,我看到您针对 iOS 8 的屏幕截图,但您的代码截图显示使用 UISearchDisplayController。此范例已被弃用,取而代之的是 UISearchController。请考虑更新。

    【讨论】:

    • 很沮丧,我没想过将becomeFirstResponder 放入viewDidAppear:。谢谢!回答您的问题:我希望它始终可见,因为 VC 专门用于搜索。 (查看 Instagram 的搜索选项卡 - 这就是我所追求的)此外,使用 UISearchDisplayController 有一个很好的理由 - 与 iOS7 兼容。它可能在 iOS8 中已被弃用,但它仍然完全有效(并且仍在 IB 的对象库中)。剩下的问题:如果您使用在导航栏中显示搜索栏的选项,为什么Apple会隐藏范围而不考虑设置showsScope = YES
    • 为什么会隐藏范围栏?我不知道,但是it is documented“如果您在导航栏中显示的搜索栏中将showsScopeBar 属性设置为YES,系统将引发异常。” 可能是因为导航栏高度不能高到无法显示范围栏。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-29
    • 1970-01-01
    • 2013-10-21
    相关资源
    最近更新 更多