[转] iOS开发-搜索栏UISearchBar和UISearchController
原文网址: http://www.cnblogs.com/xiaofeixiang/p/4273620.html?utm_source=tuicool
iOS中UISearchDisplayController用于搜索,搜索栏的重要性我们就不说了,狼厂就是靠搜索起家的,现在越来越像一匹没有节操的狼,UC浏览器搜索栏现在默认自家的神马搜索,现在不管是社交,O2O还是在线教育等都会有一个搜索栏的实现,不过彼此实现效果是不一样的。iOS中的搜索栏实现起来相对简单一点,网上也有很多参考资料,不过靠谱的不是很多,很多都是iOS 8.0之前的实现,iOS 8.0上的实现貌似很少看到,可以运行,不过会看到searchDisplayController' is deprecated: first deprecated in iOS 8.0警告,看了一些老外的代码,使用了一下UISearchController感觉还是非常不错的。
UISearchBar和UISearchDisplayController
是网上最常见的也算是最简单的,也有使用Searh Bar Search Display Controller的控件的,本文就简单的使用Search Bar和UITableView实现搜索Demo的,最上面的就是搜索栏,之前的就是TableView:
为了实现搜索需要声明委托UISearchBarDelegate,UISearchDisplayDelegate,其中搜索主要使用的就是UISearchDisplayDelegate,具体代码实现过程:
声明字段:
1
2
3
|
@property (strong, nonatomic ) NSMutableArray *dataList; @property (strong, nonatomic ) NSMutableArray *searchList; |
初始化数据:
1
2
3
4
5
|
self .dataList=[ NSMutableArray arrayWithCapacity:100]; for ( NSInteger i=0; i<100; i++) { [ self .dataList addObject:[ NSString stringWithFormat:@ "%ld-FlyElephant" ,( long )i]]; } |
设置区域:
1
2
3
4
|
//设置区域 -( NSInteger )numberOfSectionsInTableView:(UITableView *)tableView{ return 1; } |
设置区域的行数(重点),这个就是使用委托之后需要需要判断是一下是否是需要使用Search之后的视图:
1
2
3
4
5
6
7
|
-( NSInteger )tableView:(UITableView *)tableView numberOfRowsInSection:( NSInteger )section{ if (tableView == self .searchDisplayController.searchResultsTableView) { return [ self .searchList count]; } else { return [ self .dataList count]; } } |
同样的返回单元格也有两种情况,一种是初始化数据,一种是过滤之后的数据视图:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:( NSIndexPath *)indexPath{ static NSString *flag=@ "cellFlag" ; UITableViewCell *cell=[tableView dequeueReusableCellWithIdentifier:flag]; if (cell== nil ) { cell=[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:flag]; } if (tableView== self .searchDisplayController.searchResultsTableView) { [cell.textLabel setText: self .searchList[indexPath.row]]; } else { [cell.textLabel setText: self .dataList[indexPath.row]]; } return cell; } |
UISearchBarDelegate中的开始和结束的事件:
1
2
3
4
5
6
7
8
9
|
- ( BOOL )searchBarShouldBeginEditing:(UISearchBar *)searchBar{ NSLog (@ "搜索Begin" ); return YES ; } - ( BOOL )searchBarShouldEndEditing:(UISearchBar *)searchBar{ NSLog (@ "搜索End" ); return YES ; } |
搜索时过滤数据:
1
2
3
4
5
6
7
8
9
10
11
12
|
- ( BOOL )searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:( NSString *)searchString{ // 谓词的包含语法,之前文章介绍过http://www.cnblogs.com/xiaofeixiang/ NSPredicate *preicate = [ NSPredicate predicateWithFormat:@ "SELF CONTAINS[c] %@" , searchString]; if ( self .searchList!= nil ) { [ self .searchList removeAllObjects]; } //过滤数据 self .searchList= [ NSMutableArray arrayWithArray:[_dataList filteredArrayUsingPredicate:preicate]]; //刷新表格 return YES ; } |
最终效果如下:
UISearchController实现搜索
UISeachBar通过UISearchDisplayDelegate实现上面的效果是没有问题的,网上也有很多类似的实现效果,不过是警告的,信息如下: 'searchDisplayController' is deprecated: first deprecated in iOS 8.0,这么明显一个警告总不能视而不见吧,在StackOverFlow中发现UISearchDisplayController is deprecated in IOS8.0, and recommended to use UISearchController instead,也就是说iOS 8.0不推荐UISearchDisplayController,也就是不推荐使用UISearchDisplayDelegate,但是可以通过UISearchController实现UISearchResultsUpdating这个委托实现上面的效果;
视图中中需要声明UISearchResultsUpdating:
1
2
3
4
|
@interface ViewController : UITableViewController<UITableViewDelegate,UITableViewDataSource,UISearchBarDelegate,UISearchResultsUpdating> @end |
属性声明:
1
|
@property ( nonatomic , strong) UISearchController *searchController; |
需要自己初始化一下UISearchController:
1
2
3
4
5
6
7
8
9
10
11
|
_searchController = [[UISearchController alloc] initWithSearchResultsController: nil ]; _searchController.searchResultsUpdater = self ; _searchController.dimsBackgroundDuringPresentation = NO ; _searchController.hidesNavigationBarDuringPresentation = NO ; _searchController.searchBar.frame = CGRectMake( self .searchController.searchBar.frame.origin.x, self .searchController.searchBar.frame.origin.y, self .searchController.searchBar.frame.size.width, 44.0); self .tableView.tableHeaderView = self .searchController.searchBar; |
之前是通过判断搜索时候的TableView,不过现在直接使用self.searchController.active进行判断即可,也就是UISearchController的active属性:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
//设置区域的行数 -( NSInteger )tableView:(UITableView *)tableView numberOfRowsInSection:( NSInteger )section{ if ( self .searchController.active) { return [ self .searchList count]; } else { return [ self .dataList count]; } } //返回单元格内容 -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:( NSIndexPath *)indexPath{ static NSString *flag=@ "cellFlag" ; UITableViewCell *cell=[tableView dequeueReusableCellWithIdentifier:flag]; if (cell== nil ) { cell=[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:flag]; } if ( self .searchController.active) { [cell.textLabel setText: self .searchList[indexPath.row]]; } else { [cell.textLabel setText: self .dataList[indexPath.row]]; } return cell; } |
具体调用的时候使用的方法也发生了改变,这个时候使用updateSearchResultsForSearchController进行结果过滤:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
-( void )updateSearchResultsForSearchController:(UISearchController *)searchController { NSString *searchString = [ self .searchController.searchBar text]; NSPredicate *preicate = [ NSPredicate predicateWithFormat:@ "SELF CONTAINS[c] %@" , searchString]; if ( self .searchList!= nil ) { [ self .searchList removeAllObjects]; } //过滤数据 self .searchList= [ NSMutableArray arrayWithArray:[_dataList filteredArrayUsingPredicate:preicate]]; //刷新表格 [ self .tableView reloadData]; } |
效果演示:
不过两者最终实现的效果的效果基本上是一致,殊途同归,本文难免有所遗漏,如有不当,请多多指正~
参考资料:
最新文章
- VisualSVN Server搭建VDFS分布式仓研究(未成功)
- 【转】Java-----jar反编译修改重新打包
- Git 的简单使用
- LigerUI API
- php7 install memcached extension
- 了解sota字符界面(章节4.1)
- 嵌入式Linux学习小结
- 在Spring Boot中使用Spring Security实现权限控制
- ISLR系列:(4.2)模型选择 Ridge Regression &; the Lasso
- border-radius 圆角
- java中的反射整理
- Java开发规范总结
- Get teststep of specific type
- Linux初次修改环境变量
- 最新手机号码验证正则表达式(PHP版本)
- 深度学习原理与框架-Tensorflow卷积神经网络-cifar10图片分类(代码) 1.tf.nn.lrn(局部响应归一化操作) 2.random.sample(在列表中随机选值) 3.tf.one_hot(对标签进行one_hot编码)
- aliyun服务器对象存储oss
- Bi-shoe and Phi-shoe
- 高并发架构技术|缓存失效、缓存穿透问题 PHP 代码解决
- tilestache + mbutil应用
热门文章
- debian7 amd64版本添加对x86包的支持
- 算法(Algorithms)第4版 练习 1.3.25 1.3.24
- bootstrap.min.css.map
- jQuery蓝色修边tab标签切换
- mysql八:ORM框架SQLAlchemy
- VC++中list::list的使用方法总结
- 一些rtsp实现的开源代码
- deep QA 基于生成的chatbot系统
- linux 几个逼格高实用的命令
- 「LOJ#10068」「一本通 3.1 练习 3」秘密的牛奶运输(次小生成树