iOS中的两种搜索方式UISearchDisplayController和UISearchController

                       
 

大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处.
  如果觉得写的不好请多提意见,如果觉得不错请多多支持点赞.谢谢! hopy ;)


以前iOS的搜索一般都使用UISearchDisplayController来完成,不过自从iOS 8.0开始,该控制器被标记为废弃,我们可以在iOS 8.0之后使用一个新的搜索控制器UISearchController来完成搜索.

本篇博文将介绍以上2种搜索控制器的简单用法,并比较它们的区别.Let’t Go!

UISearchDisplayController

使用该控制器我们必须给根控制器添加一个UISearchDisplayDelegate协议,然后完成其规定的几个回调方法:

-(BOOL)searchDisplayController:(UISearchDisplayController *)controller                                shouldReloadTableForSearchString:(NSString *)searchString{    [_filteredNames removeAllObjects];    if (searchString.length > 0) {        NSPredicate *predicate = [NSPredicate predicateWithBlock:                                    ^BOOL(NSString *name,NSDictionary *b) {            NSRange range = [name rangeOfString:searchString options:NSCaseInsensitiveSearch];            return range.location != NSNotFound;        }];        for (NSString *key in _keys) {            NSArray *matchs = [_names[key] filteredArrayUsingPredicate:predicate];            [_filteredNames addObjectsFromArray:matchs];        }    }    return YES;}-(void)searchDisplayController:(UISearchDisplayController *)controller                                    didLoadSearchResultsTableView:(UITableView *)tableView{    [tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:SectionsTableID];}
   
   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

其中第一个方法在搜索关键字发生改变时调用,后一个则在搜索表视图加载完毕后调用,我们可以看见如上代码所示,我们在搜索表视图加载后将其表视图的UITableViewCell元素的ID和一个特定的ID绑定,这样做可以重用已存在的单元格.另外需要注意的是该ID和根视图控制器中标示图的单元格ID是一样的,虽然这两个表视图是不一样的.

我们在根视图控制器的didLoadView中用以下代码初始化UISearchDisplayController:

UISearchBar *searchBar = [[UISearchBar      alloc]initWithFrame:CGRectMake(0, 0, 320, 44)];tableView.tableHeaderView = searchBar;_searchController = [[UISearchDisplayController alloc]initWithSearchBar:searchBar                                       contentsController:self];_searchController.delegate = self;_searchController.searchResultsDataSource = self;
   
   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

以上代码首先创建一个searchBar并将其设置为tableView的表头视图,接着以该searchBar为参数创建UISearchDisplayController对象,最后设置好其对应的委托.

因为此时根视图中存在2个表视图,所以我们在处理相关回调方法时要区分当前处理的是哪张表视图:

-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{    if (tableView.tag == 1) {        return _keys.count;    }else{        return 1;    }}
   
   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

我们将默认的呈现数据的表视图的tag设置为1,这样我们就知道当前需要处理的是哪张表视图了.其它的回调与此类似,不再一一述及.

UISearchController

下面我们来看看iOS 8.0之后新的搜索器类的使用方法.首先我们也必须添加一个UISearchResultsUpdating协议,同时实现一个协议方法:

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

该方法和前一个搜索器类的方法类似,不过要注意的是它不返回值,这意味着如果你想要显示搜索结果,你必须手动刷新表视图.下面给出一个该方法的例子:

-(void)updateSearchResultsForSearchController:(UISearchController *)searchController{    NSString *searchString = _searchController.searchBar.text;    [_filteredNames removeAllObjects];    if (searchString.length > 0) {        NSPredicate *predicate = [NSPredicate predicateWithBlock:                                  ^BOOL(NSString *name,NSDictionary *b) {                                      NSRange range = [name rangeOfString:searchString options:NSCaseInsensitiveSearch];                                      return range.location != NSNotFound;                                  }];        for (NSString *key in _keys) {            NSArray *matchs = [_names[key] filteredArrayUsingPredicate:predicate];            [_filteredNames addObjectsFromArray:matchs];        }    }else{        //如果搜索关键字为空则显示所有key        for (NSString *key in _keys) {            NSArray *matchs = _names[key];            [_filteredNames addObjectsFromArray:matchs];        }    }    UITableView *tableView = [self.view viewWithTag:1];    //手动刷新表视图    [tableView reloadData];}
   
   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

UISearchController还有一个和UISearchDisplayController不同的地方,就是判断当前表视图是否是搜索表视图的方法:

-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{    if (_searchController.active) {        return 1;    }else{        return _keys.count;    }}
   
   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

好吧,我收回上面的话…准确来说,应该是前者根本没有自己的表视图,它使用的表视图就是默认的表视图.也就是我们必须自默认的表视图中判断当前搜索是否激活,如果是则显示搜索后的结果,否则显示默认呈现的数据.

最后我们来看看,如何初始化UISearchController:

_searchController = [[UISearchController alloc]initWithSearchResultsController:nil];    _searchController.searchResultsUpdater = self;    _searchController.dimsBackgroundDuringPresentation = NO;    _searchController.hidesNavigationBarDuringPresentation = NO;    tableView.tableHeaderView = _searchController.searchBar;
   
   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

大家可以看到不用再自己创建UISearchBar对象了,UISearchDisplayController已经帮你搞定了.

总结

最后我们来看一下以上2种搜索控制器的不同:

  1. 前者使用单独的表视图,后者没有表视图,其内容使用默认的表视图来呈现.
  2. 前者需要手动创建UISearchBar对象,而后者不需要
  3. 前者需要在表示图的协议回调中判断当前是哪个表视图,而后者只是简单判断搜索是否处在激活状态
  4. 它们遵守的协议不一样,协议方法自然也不一样
  5. 前者比较复杂,后者更简单,从类的构成上来说也更合理.
           

再分享一下我老师大神的人工智能教程吧。零基础!通俗易懂!风趣幽默!还带黄段子!希望你也加入到我们人工智能的队伍中来!https://blog.csdn.net/jiangjunshow

猜你喜欢

转载自blog.csdn.net/qq_43678568/article/details/86226508
今日推荐