我如何在 iOS 8 中使用 UISearchController,其中 UISearchBar 在我的导航栏中并且具有范围按钮?

How do I use UISearchController in iOS 8 where the UISearchBar is in my navigation bar and has scope buttons?

我正在尝试使用 iOS 8 中的新 UISearchController,并将其 UISearchBar 嵌入到我的 UINavigationBar 中。这很容易完成,如下所示:

searchController = UISearchController(searchResultsController: nil)
searchController.searchResultsUpdater = self
searchController.delegate = self
searchController.searchBar.delegate = self
searchController.dimsBackgroundDuringPresentation = false
searchController.hidesNavigationBarDuringPresentation = false
navigationItem.titleView = searchController.searchBar

但是当我添加范围按钮时:

searchController.searchBar.showsScopeBar = true
searchController.searchBar.scopeButtonTitles = ["Posts, Users, Subreddits"]

它在UISearchBar后面添加了按钮,显然看起来很奇怪。

我应该怎么做?

您遇到了 "design issue",其中 scopeBar 预计会在 searchController 未激活时被隐藏。

范围栏按钮出现在搜索栏后面(下方),因为当搜索栏激活并自动进入导航栏时,它们就位于此位置。

当搜索未处于活动状态时,可见范围栏会占据屏幕 space,分散用户对内容的注意力,并使用户感到困惑(因为范围按钮没有结果过滤)。

由于您的 searchBar 已经位于 titleView 中,因此不会出现显示范围栏的(导航和搜索)栏动画。

  • 最简单选项是将搜索栏定位在 导航栏,并让 searchBar 动画化到标题中 激活时的区域。导航栏将为其高度设置动画, 腾出空间来包含隐藏的范围栏。这将所有 由搜索控制器处理。
  • 第二个选项,几乎同样简单,是使用 搜索 栏按钮 图标,它将 searchBarscopeBar 动画化为 在导航栏上查看。

    - (IBAction)searchButtonClicked:(UIBarButtonItem *)__unused sender {
        self.searchController = [[UISearchController alloc] initWithSearchResultsController:nil];
        self.searchController.searchResultsUpdater = self;
        self.searchController.hidesNavigationBarDuringPresentation = NO;
        self.searchController.dimsBackgroundDuringPresentation = NO;
        self.definesPresentationContext = YES;
        self.searchController.searchBar.scopeButtonTitles = @[@"Posts", @"Users", @"Subreddits"];
        [self presentViewController:self.searchController animated:YES completion:nil];
    }
    
  • 如果想让searchBar留在titleView中,一个动画 做你想做的不是内置的。你必须自己动手 处理导航栏高度变化并显示你自己的代码 范围栏(或挂钩到内部,并为 built-in 设置动画 scopeBar 向下并进入视野。

    如果幸运的话,其他人已经编写了 willPresentSearchController: 代码来处理您想要的转换。

  • 如果您希望始终看到 searchBarscopeBar,您可能不得不放弃使用 built-in scopeBar,并且将其替换为用户将始终看到的 UISegmentedControl,即使搜索控制器未处于活动状态。

更新:

This answer 建议继承 UISearchController 以更改其 searchBar 的高度。