[转] 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]; } |
效果演示:
不过两者最终实现的效果的效果基本上是一致,殊途同归,本文难免有所遗漏,如有不当,请多多指正~
参考资料:
[转] iOS开发-搜索栏UISearchBar和UISearchController的更多相关文章
- iOS开发-搜索栏UISearchBar和UISearchController
iOS中UISearchDisplayController用于搜索,搜索栏的重要性我们就不说了,狼厂就是靠搜索起家的,现在越来越像一匹没有节操的狼,UC浏览器搜索栏现在默认自家的神马搜索,现在不管是社 ...
- iOS开发之直接使用UISearchBar
iOS开发中经常需要使用SearchBar,我们可以选择使用UISearchBar+UISearchController或者UISearchBar+UISearchDisplayController( ...
- IOS开发UISearchBar失去第一响应者身份后,取消按钮不执行点击事件的问题
在iOS开发中,使用UISearchBar的时候,当搜索框失去焦点的时候,取消按钮是默认不能点击的,如图按钮的颜色是灰色的: 这是因为此时取消按钮的enabled属性被设置为NO了,那么当我们需要让 ...
- ios开发入门篇(四):UIWebView结合UISearchBar的简单用法
UIWebView是ios开发中比较常用的一个控件.我们可以用它来浏览网页.打开文档等,今天笔者在这里简单介绍下UIWebView和UISearchBar结合起来的用法,做一个简单的类浏览器. 一: ...
- iOS开发系列--UITableView全面解析
--UIKit之UITableView 概述 在iOS开发中UITableView可以说是使用最广泛的控件,我们平时使用的软件中到处都可以看到它的影子,类似于微信.QQ.新浪微博等软件基本上随处都是U ...
- iOS开发ARC入门和使用
本文引自:http://www.onevcat.com/2012/06/arc-hand-by-hand/ 英文原版:http://www.raywenderlich.com/5677/beginni ...
- 《iOS开发实战 从入门到上架App Store(第2版)》书籍目录
第1章 开发准备 1.1 iOS 10新特性简述 1.1.1 新增触觉反馈编程接口 1.1.2 SiriKit框架的开放 1.1.3 引入Messages App 1.1.4 通知框架的整合与扩展 1 ...
- iOS开发系列--网络开发
概览 大部分应用程序都或多或少会牵扯到网络开发,例如说新浪微博.微信等,这些应用本身可能采用iOS开发,但是所有的数据支撑都是基于后台网络服务器的.如今,网络编程越来越普遍,孤立的应用通常是没有生命力 ...
- IOS开发基础知识碎片-导航
1:IOS开发基础知识--碎片1 a:NSString与NSInteger的互换 b:Objective-c中集合里面不能存放基础类型,比如int string float等,只能把它们转化成对象才可 ...
随机推荐
- 同源策略 , CORS
一 . 同源策略 同源策略( Same origin policy ) 是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,则浏览器的正常功能可能都会受到影响,可以说Web是构建在同源 ...
- 《C prime plus (第五版)》 ---第11章 字符串和字符串函数
11-1:字符串表示和字符串I/O 1.首先先通过一个整体的例子来初步了解建立,读入和输出字符串的几种方式. #include<stdio.h> #define MSG "你一定 ...
- 一次php脚本出现段错误(Segment fault)的经历
今天在一台新服务器上cli运行一个php脚本,出现了Segment fault错误,第一感觉应该是某个扩展安装有问题 这段php代码是调用soap接口,查看soap扩展没啥问题,一时不知道是啥原因. ...
- C++中vector使用详细说明
1. 在C++中的详细说明 vector是C++标准模板库中的部分内容,它是一个多功能的,能够操作多种数据结构和算法的模板类和函数库. vector之所以被认为是一个容器,是因为它能够像容器一样存放各 ...
- jmeter-sampler(取样器)HTTP请求
名称:用于标识一个sample. 注释:对于测试没任何影响,仅用来记录用户可读的注释信息. 服务名称或IP:http请求发送的目标服务器名称或者IP地址,比如:http://www.baidu.com ...
- listen 73
Give Time to Feel Less Time-Squeeze Meetings, calls, kids, dogs, errands, exercise—and all those ema ...
- 初识Spacy
之所以想接触Spacy,是看到其自称为工业级的应用,所以想尝试下 windows下安装Spacy: 直接安装pip install spacy是会报错的 解决方法: 到 htt ...
- PC样式reset参考
/* html5doctor.com Reset Stylesheet */ * { padding:; margin:; list-style: none; } html, body, div, s ...
- javacpp-FFmpeg系列补充:FFmpeg拉流截图实现在线演示demo(视频截图并返回base64图像,支持jpg/png/gif/bmp等多种格式)
javacpp-ffmpeg系列: javacpp-FFmpeg系列之1:视频拉流解码成YUVJ420P,并保存为jpg图片 javacpp-FFmpeg系列之2:通用拉流解码器,支持视频拉流解码并转 ...
- 向nexus远程仓库里面添加JAR
向nexus远程仓库里面添加JAR 远程仓库:http://10.1.252.21:8081/nexus/index.html admin/admin123 方法一:手动 在左侧选择:Reposito ...