UISearchController

作者: __Simon__ | 来源:发表于2017-06-21 17:33 被阅读82次

    UISearchController 是一个非常好用的搜索控件,看中的就是他的模态动画。能够快速实现想要的效果。

    Demo效果

    UISearchController 的基本属性

    // 输入框内容发生变化的时候做出响应的代理
    @property (nullable, nonatomic, weak) id <UISearchResultsUpdating> searchResultsUpdater;
    
    // 待了解
    @property (nonatomic, assign, getter = isActive) BOOL active;
    
    // UISearchController 的代理对象
    @property (nullable, nonatomic, weak) id <UISearchControllerDelegate> delegate;
    // 设置背景灰暗,默认值为 YES
    @property (nonatomic, assign) BOOL dimsBackgroundDuringPresentation 
    // 设置背景模糊,默认值为 YES
    @property (nonatomic, assign) BOOL obscuresBackgroundDuringPresentation 
    // 模态的时候隐藏导航栏,默认值为 YES
    @property (nonatomic, assign) BOOL hidesNavigationBarDuringPresentation;
    // 显示搜索结果的视图控制器
    @property (nullable, nonatomic, strong, readonly) UIViewController *searchResultsController;
    // UISearchController内置的UISearchBar
    @property (nonatomic, strong, readonly) UISearchBar *searchBar;
    

    使用当前页面展示搜索结果

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

    当初始化方法的initWithSearchResultsController:传值为nil的时候,表示使用当前页面作为结果展示页面

    使用SearchResultsController 展示搜索结果

    ResultViewController *resultVC = [[ResultViewController alloc] initWithNibName:@"ResultViewController" bundle:nil];
    self.searchController = [[UISearchController alloc] initWithSearchResultsController:resultVC];
    // 这行代码是必须要加上的
    self.definesPresentationContext = YES;
    

    当初始化方法的initWithSearchResultsController:传值为结果展示页面的视图控制器resultVC时,表示搜索结果在指定页面显示。

    并且要写上下面这行代码来定义UISearchController只在当前视图模态出现,否也页面会出现奇奇怪怪的问题。

    // 定义模态的上下文
    self.definesPresentationContext = YES;
    

    代理方法

    UISearchResultsUpdating

    - (void)updateSearchResultsForSearchController:(UISearchController *)searchController;
    

    SearchBar的输入框内容发生变化的时候会调用此代理方法,在此方法中可以实时处理一些对数据的获取过滤操作

    UISearchControllerDelegate

    // UISearchController 将要模态出来的代理方法
    - (void)willPresentSearchController:(UISearchController *)searchController;
    // UISearchController 已经模态出来的代理方法
    - (void)didPresentSearchController:(UISearchController *)searchController;
    // UISearchController 将要隐藏的代理方法
    - (void)willDismissSearchController:(UISearchController *)searchController;
    // UISearchController 已经隐藏的代理方法
    - (void)didDismissSearchController:(UISearchController *)searchController;
    
    // Called after the search controller's search bar has agreed to begin editing or when 'active' is set to YES. If you choose not to present the controller yourself or do not implement this method, a default presentation is performed on your behalf.
    - (void)presentSearchController:(UISearchController *)searchController;
    

    注意点

    • 当使用子页面展示搜索结果的时候,一定要注意使用UISearchController所在的页面的UINavigationControllerpush出子页面. 可以使用Block或者Delegate实现将子页面的点击跳转事件转移到父级页面去处理。如果使用结果页面的UINavigationController会导致子页面push出的子页面上有一个UISearchBar

    • UISearchController默认的实现是点击UISearchBar的时候不显SearchResultsController,如果要实现点击SearchBar立马就显示搜索结果页面可以使用KVO 监听SearchResultsController.viewhidden属性,保证hidden属性的值一直为NO。如下代码所示

    
    - (void)configSearchController {
        
        ResultViewController *resultVC = [[ResultViewController alloc] initWithNibName:@"ResultViewController" bundle:nil];
        
        self.searchController = [[UISearchController alloc] initWithSearchResultsController:resultVC];
        self.searchController.delegate = self;
        self.searchController.searchResultsUpdater = self;
        self.searchController.searchBar.delegate = self;
        self.searchController.dimsBackgroundDuringPresentation = YES;
        self.searchController.obscuresBackgroundDuringPresentation = YES;
        self.searchController.hidesNavigationBarDuringPresentation = YES;
        self.tableView.tableHeaderView = self.searchController.searchBar;
        /**
          使用KVO可能会造成崩溃,所以慎用。KVO可能造成崩溃的原因
          1. 对象已经销毁KVO监听依然存在
          2. 过多的删除KVO的监听
        */
        [self.searchController.searchResultsController.view addObserver:self forKeyPath:@"hidden" options:0 context:NULL];
    }
    
    - (void)observeValueForKeyPath:(NSString *)keyPath
                          ofObject:(id)object
                            change:(NSDictionary *)change
                           context:(void *)context
    {
        if ( object == self.searchController.searchResultsController.view &&
            [keyPath isEqualToString:@"hidden"] &&
            self.searchController.searchResultsController.view.hidden &&
            self.searchController.searchBar.isFirstResponder )
        {
            // 确保结果页一直显示
            self.searchController.searchResultsController.view.hidden = NO;
        }
    }
    
    

    Demo的地址

    这是目前我能想到的处理方式,如果有更好的处理方式请留言。

    相关文章

      网友评论

        本文标题:UISearchController

        本文链接:https://www.haomeiwen.com/subject/pcytcxtx.html