UISearchController是iOS 8新添加的一个class,以来替代之前的UISearchDisplayController。

The UISearchController class defines an interface that manages the presentation of a search bar in concert with the search results controller’s content.

SearchResultsController

在初始化UISearchController之前,需要先设计好它的searchResultsController

searchResultsController用以管理和呈现搜索结果,是UIViewController类型的。通常设计为UITableViewController

JWSearchResultsController是我做的一个基于UITableViewController类的searchResultsController,项目中还有一些使用示例。

- initWithSearchResultsController:

通过这个方法,创建UISearchController

JWSearchResultsController *searchResultsController = [self.storyboard instantiateViewControllerWithIdentifier:JWSearchResultsVCIdentifier];

self.searchController = [[UISearchController alloc] initWithSearchResultsController:searchResultsController];

Launch Style

完成初始化后,下一步确定UISearchController将会在什么位置以何种形式被唤起。

  1. Search Button

    Search Button

    通过点击搜索按钮,UISearchController出现在当前界面的上方。

    • self.searchController.hidesNavigationBarDuringPresentation = NO;
      [self presentViewController:self.searchController animated:YES completion:nil];
  2. 内嵌于TableView的顶部

    TableView

    点击搜索框,搜索框会滑到屏幕的顶部;或者搜索框在原有位置展开。

    • //    self.searchController.hidesNavigationBarDuringPresentation = NO;
       self.tableView.tableHeaderView = self.searchController.searchBar;
       self.definesPresentationContext = YES;
  3. 内嵌于NavigationBar

    Navigator

    搜索框直接位于导航栏的内部。

    注意:这种情况下就不要设置searchBar.scopeButtonTitles了,会因为显示区域太小而重叠在一起;searchBar.searchBarStyle也应该设置为UISearchBarStyleMinimal

    • //    self.searchController.searchBar.scopeButtonTitles = @[@"All", ProductTypeMobile, ProductTypeDesktop, ProductTypePortable];
      self.searchController.searchBar.searchBarStyle = UISearchBarStyleMinimal;
      self.searchController.hidesNavigationBarDuringPresentation = NO;
      self.navigationItem.titleView = self.searchController.searchBar;
      self.definesPresentationContext = YES;

delegate

search controller的代理,遵从<UISearchControllerDelegate>协议。主要是监听search controller显示逻辑方面的改变。

self.searchController.delegate = self;

#pragma mark - UISearchControllerDelegate
- (void)willPresentSearchController:(UISearchController *)searchController
{
    // Called when the search controller is to be automatically displayed.
}

searchResultsUpdater

searchResultsUpdater是一个属性,表示该updater负责更新搜索的结果,遵从<UISearchResultsUpdating>协议。

当搜索框成为first responder;框内的输入发生改变;搜索框的scope发生变化时,都会自动触发update方法。

self.searchController.searchResultsUpdater = self;

#pragma mark - UISearchResultsUpdating
-(void)updateSearchResultsForSearchController:(UISearchController *)searchController {
    /*
    This method is automatically called whenever the search bar becomes the first responder or changes are made to the text or scope of the search bar. 
    */
}

searchBar 及 UISearchBarDelegate

searchBar属性是UISearchController内嵌的搜索栏,UISearchBar类型。

实现<UISearchBarDelegate>可以监听searchBar的变化。

self.searchController.searchBar.scopeButtonTitles = @[@"All", ProductTypeMobile, ProductTypeDesktop, ProductTypePortable];

self.searchController.searchBar.delegate = self;

#pragma mark - UISearchBarDelegate
- (void)searchBar:(UISearchBar *)searchBar selectedScopeButtonIndexDidChange:(NSInteger)selectedScope
{
    // Tells the delegate that the scope button selection changed.
}

NSPredicate

搜索过程中一般使用NSPredicate

NSPredicate *namePredicate = [NSPredicate predicateWithFormat:@"name CONTAINS [c] $nameString"];
[self.searchResults filterUsingPredicate:[namePredicate predicateWithSubstitutionVariables:@{@"nameString":searchString}]];