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];
}
其中第一个方法在搜索关键字发生改变时调用,后一个则在搜索表视图加载完毕后调用,我们可以看见如上代码所示,我们在搜索表视图加载后将其表视图的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;
以上代码首先创建一个searchBar并将其设置为tableView的表头视图,接着以该searchBar为参数创建UISearchDisplayController对象,最后设置好其对应的委托.
因为此时根视图中存在2个表视图,所以我们在处理相关回调方法时要区分当前处理的是哪张表视图:
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
if (tableView.tag == 1) {
return _keys.count;
}else{
return 1;
}
}
我们将默认的呈现数据的表视图的tag设置为1,这样我们就知道当前需要处理的是哪张表视图了.其它的回调与此类似,不再一一述及.
UISearchController
下面我们来看看iOS 8.0之后新的搜索器类的使用方法.首先我们也必须添加一个UISearchResultsUpdating协议,同时实现一个协议方法:
-(void)updateSearchResultsForSearchController:(UISearchController *)searchController;
该方法和前一个搜索器类的方法类似,不过要注意的是它不返回值,这意味着如果你想要显示搜索结果,你必须手动刷新表视图.下面给出一个该方法的例子:
-(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];
}
UISearchController还有一个和UISearchDisplayController不同的地方,就是判断当前表视图是否是搜索表视图的方法:
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
if (_searchController.active) {
return 1;
}else{
return _keys.count;
}
}
好吧,我收回上面的话…准确来说,应该是前者根本没有自己的表视图,它使用的表视图就是默认的表视图.也就是我们必须自默认的表视图中判断当前搜索是否激活,如果是则显示搜索后的结果,否则显示默认呈现的数据.
最后我们来看看,如何初始化UISearchController:
_searchController = [[UISearchController alloc]initWithSearchResultsController:nil];
_searchController.searchResultsUpdater = self;
_searchController.dimsBackgroundDuringPresentation = NO;
_searchController.hidesNavigationBarDuringPresentation = NO;
tableView.tableHeaderView = _searchController.searchBar;
大家可以看到不用再自己创建UISearchBar对象了,UISearchDisplayController已经帮你搞定了.
总结
最后我们来看一下以上2种搜索控制器的不同:
- 前者使用单独的表视图,后者没有表视图,其内容使用默认的表视图来呈现.
- 前者需要手动创建UISearchBar对象,而后者不需要
- 前者需要在表示图的协议回调中判断当前是哪个表视图,而后者只是简单判断搜索是否处在激活状态
- 它们遵守的协议不一样,协议方法自然也不一样
- 前者比较复杂,后者更简单,从类的构成上来说也更合理.
iOS中的两种搜索方式UISearchDisplayController和UISearchController的更多相关文章
- iOS中的两种主要架构及其优缺点浅析
凡是程序的开发者,应该对程序的架构都不陌生.一个程序的架构的好坏对这个程序有着非常重要的作用.今天我们来看一下iOS开发中用要的两种主流的程序架构.这个过程中我们主要以例子的形式展开. 我们来看第一种 ...
- Javaweb学习笔记——(六)——————xml中jaxp两种解析方式和dom4j运用
1.xml的scheam约束 dtd的语法:<!ElEMENT 元素名称 约束> **schema符合xml的语法,xml语句 **一个xml中可以有多个schema,多个schema使用 ...
- javascript中对象两种创建方式
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- String中的两种实例化方式的区别
直接赋值:(String str = "字符串");只会开辟一块堆内存空间,并且会自动保存在对象池中以供下次重复使用. 构造方法:(String str = new String ...
- web 开发之js---ajax 中的两种提交方式ajax post 和 ajax get 实例
()post http://04101334.iteye.com/blog/637695/ ()get function serializeElement(element) { var method ...
- class类名在webpack项目中的两种引用方式
一.问题描述 在项目工程中,我们通常既用到css module,也用到普通的less文件引用方式,代码及webpack配置如下,运行时,发现只有css module起作用,如何让两者都起作用呢? // ...
- Hibeernate中的两种分页方式
1. return getHibernateTemplate().executeFind(new HibernateCallback() { public Object doInHibernate(S ...
- ios中的界面跳转方式
ios中,两种界面跳转方式 1.NavgationController本身可以作为普通ViewController的容器,它有装Controller的栈,所以可以push和pop它们,实现你所说的跳转 ...
- hibernate 一对一 one to one的两种配置方式
hibernate中one-to-one两种配置方式 标签: hibernateHibernateone-to-one 2013-02-19 17:44 11445人阅读 评论(1) 收藏 举报 分 ...
随机推荐
- 关于java线程中stop interrupt daemon wait notify
一.关于终止线程stop与interrupt 一般来说,线程执行结束后就变成消亡状态,乍看之下我们并不需要人为进行干预(人为停止线程),不过凡事都有例外吧,在服务器或者其他应用场景下,线程为了提供服务 ...
- 笔记11 在XML中声明切面(2)
为通知传递参数 1.声明一个CompactDiscs接口.内部包含两个方法: show() 用于显示唱片的名字和艺术风格 playTrack(int number) 根据传入的磁道数播放相应磁道的音乐 ...
- ES6(数值)
数值处理新增特性: 1.新增方法 2.方法调整 1.二进制和八进制 二进制以 0b 开头,其中B和b都可以:八进制以 0o 开头,其中O和o都可以. 2.判断数值是否有效(有限) NaN为非数字,故为 ...
- PTA 旅游规划(25 分)
7-10 旅游规划(25 分) 有了一张自驾旅游路线图,你会知道城市间的高速公路长度.以及该公路要收取的过路费.现在需要你写一个程序,帮助前来咨询的游客找一条出发地和目的地之间的最短路径.如果有若干条 ...
- Linux 定时执行任务:Crontab服务及应用集锦
系统背景:cenos6.5 操作工具:Xshell5 情况一:正常情况(系统有service命令) 重启服务命令:[root@centos6 /]# service crond restart 启动服 ...
- WIN2008虚拟机安装ORACLE11g记录
---恢复内容开始--- 1.ORACLE11g的安装包下载与解压 官网下载地址:(http://www.oracle.com/technetwork/database/enterprise-edit ...
- AnyConnect使用说明(手机版)
一.下载安装客户端 iPhone手机在App Store 里搜索 “Anyconnect”下载安装. Android手机需另外下载Anyconnect. 二. 1.打开AnyConnect,点击&qu ...
- k8s Kubernetes v1.10 最简易安装 shell
k8s Kubernetes v1.10 最简易安装 shell # Master 单节点快速安装 # 最简单的安装shell,只为快速部署k8s测试环境 #环境centos 7.4 #1 初始化环境 ...
- Dynamics CRM2016 Web API之删除单个查找字段值
之前的博文中有介绍过,Web Api中的一个删除单个属性的Api但没提供查找字段的删除方法,本篇补充上,这里给出的示例代码是C#的(主要看url的拼接),看下url中最后的/$ref,这个标示表明了当 ...
- webpack dev server 和 sublime text 配合时需要注意的地方
参考:https://webpack.js.org/guides/development/ Adjusting Your Text Editor Some text editors have a &q ...