UISearchController替换UISearchDisplayController
随着iOS 的升级,iOS 7的占有率更低了。Xcode 升级到Xcode 8之后,对iOS 应用支持的最低版本,iOS 7也被抛弃了。我在新项目中也是最低支持到iOS 8,因此工程里也是各种警告。首先看到的就是UISearchDisplayController
建议替换为UISearchController
。
以前的搜索功能回顾
以前我们要在表格头部加一个搜索功能是这样写的:
//解决搜索栏在取消时,抖动问题。
[self setAutomaticallyAdjustsScrollViewInsets:YES];
[self setExtendedLayoutIncludesOpaqueBars:YES];
//设置搜索框
UISearchBar *searchBar = [[UISearchBar alloc] initWithFrame:CGRectMake(0, 0, kScreenWidth, 44)];
searchBar.delegate = self;
searchBar.placeholder = @"精确搜索:通过昵称或手机号码";
searchBar.tintColor = kThemeColor;
self.searchDisplayVC = [[UISearchDisplayController alloc] initWithSearchBar:searchBar contentsController:self];
self.searchDisplayVC.searchResultsDataSource = self;
self.searchDisplayVC.searchResultsDelegate = self;
self.searchDisplayVC.searchResultsTableView.rowHeight = 64;
UIView *view = [UIView new];
view.backgroundColor = [UIColor clearColor];
self.searchDisplayVC.searchResultsTableView.tableFooterView = view;
self.tableView.tableHeaderView = searchBar;
self.tableView.rowHeight = 50;
self.tableView.tableFooterView = [UIView new];
可以看到,如果我们要在表格头部加一个搜索框,需要初始化UISearchBar和UISearchDisplayController,还需要设置一堆东西。还是挺麻烦的!
然后就是要实现,UISearchBar的一个代理方法(当然我们可以实现UISearchDisplayController的代理方法):
#pragma mark - UISearchBarDelegate
- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar
{
[self.searchArray removeAllObjects];
// 这里是搜索操作
NSPredicate *searchPredicate = [NSPredicate predicateWithFormat:@"self contains[cd] %@",_searchController.searchBar.text];
self.searchArray = [[self.titles filteredArrayUsingPredicate:searchPredicate] mutableCopy];
//刷新搜索表格
[_searchDisplayVC.searchResultsTableView reloadData];
}
然后tableView 的数据源代理也需要区分是否为搜索表格
#pragma mark - UITableViewDataSource
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if (tableView == _tableView) {
return _titles.count;
}
return _searchArr.count;
}
新的搜索功能实现
iOS 8以后,苹果推荐使用UISearchController,如果在初始化的时候,没有设置searchResultsController,那么搜索结果就在代理对象控制器的表格中显示。
_searchController = [[UISearchController alloc] initWithSearchResultsController:nil];
_searchController.searchResultsUpdater = self;
// 默认为YES,控制搜索控制器的灰色半透明效果
// _searchController.dimsBackgroundDuringPresentation = NO;
// 默认为YES,控制搜索时,是否隐藏导航栏
// _searchController.hidesNavigationBarDuringPresentation = NO;
_searchController.searchBar.delegate = self;
_searchController.searchBar.placeholder = @"请输入...";
_searchController.searchBar.tintColor = [UIColor orangeColor];
_searchController.searchBar.barTintColor = [UIColor greenColor];
[_searchController.searchBar sizeToFit];
self.definesPresentationContext = YES;
self.tableView.tableHeaderView = _searchController.searchBar;
self.tableView.tableFooterView = [UIView new];
接下来也是实现代理方法:
- (void)updateSearchResultsForSearchController:(UISearchController *)searchController
{
[self.searchArray removeAllObjects];
//执行搜索操作
NSPredicate *searchPredicate = [NSPredicate predicateWithFormat:@"self contains[cd] %@",_searchController.searchBar.text];
self.searchArray = [[self.titles filteredArrayUsingPredicate:searchPredicate] mutableCopy];
//刷新表格
[self.tableView reloadData];
}
因为搜索结果和正常情况使用的是同一个tableView,那么如何区分搜索时显示搜索的数据源呢?
通过UISearchController
的active属性即可判断,这是一个BOOL类型的属性。
示例代码:
#pragma mark - UITableViewDataSource
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if (_searchController.active) {
return self.searchArray.count;
}
return self.titles.count;
}
其实到这里,表格头部的搜索功能就完成了。
下面还有一些可能出现的Bug或场景解决方案。
1.如果我不需要实时显示搜索结果怎么处理?
显然,如果我们搜索功能的结果需要服务器返回,那么就不应该在用户输入每个字母的时候都去请求一次。应该是用户输入完关键字,点击搜索后再去搜索。
那么这时,就需要先实现UISearchBar 的UISearchBarDelegate
中的代理方法:
#pragma mark - UISearchBarDelegate
- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar
{
[self.searchArray removeAllObjects];
//执行搜索操作
NSPredicate *searchPredicate = [NSPredicate predicateWithFormat:@"self contains[cd] %@",_searchController.searchBar.text];
self.searchArray = [[self.titles filteredArrayUsingPredicate:searchPredicate] mutableCopy];
//刷新表格
[self.tableView reloadData];
}
然后,还必须实现的UISearchController
的UISearchResultsUpdating
中的代理方法:
- (void)updateSearchResultsForSearchController:(UISearchController *)searchController
{
//刷新表格
[self.tableView reloadData];
}
可以看一下上面这个代理方法的注释:
// Called when the search bar's text or scope has changed or when the search bar becomes first responder.
当搜索框中的内容,范围发生变化,或者搜索框成为或者取消第一响应者时,会被调用。
所以需要在这里刷新一下tableView 来更新数据源,因为他们用的是同一个tableView展示数据。
怎么证明呢?
很简单,只需要在tableView 的数据源方法中打印一下tableView,看他们是否是同一个TableView对象即可。
// 正常情况下的tableView
<UITableView: 0x7f86aa113000; frame = (0 0; 320 504); clipsToBounds = YES; autoresize = RM+BM; gestureRecognizers = <NSArray: 0x600000241c20>; layer = <CALayer: 0x6000000354c0>; contentOffset: {0, 0}; contentSize: {320, 0}>
// 搜索输入框被激活时的tableView
<UITableView: 0x7f86aa113000; frame = (0 0; 375 603); clipsToBounds = YES; autoresize = RM+BM; gestureRecognizers = <NSArray: 0x600000241c20>; layer = <CALayer: 0x6000000354c0>; contentOffset: {0, 0}; contentSize: {375, 3344}>
2.设置搜索栏背景色
直接上代码了:
_searchController.searchBar.barTintColor = [UIColor greenColor];
当然,在以前的实现方式里,也可以直接设置searchBar的barTintColor来修改搜索栏的背景色。(这个属性是iOS 7之后加的)
3.改变搜索栏 “取消”按钮和 光标的颜色
还是直接上代码:
_searchController.searchBar.tintColor = [UIColor orangeColor];
4.使用UISearchController如何在搜索时将搜索栏移动到导航栏上
这个问题的解决方案需要设置两个地方:
第一,确保UISearchController 的hidesNavigationBarDuringPresentation
为YES(这个属性默认就是YES,你要确定你没修改过这个属性)。
第二,将当前控制器的definesPresentationContext
设置为YES。即:
self.definesPresentationContext = YES;
UISearchController替换UISearchDisplayController的更多相关文章
- iOS--- UITableView + UISearchDisplayController - - - - -实现搜索功能
iOS中UISearchDisplayController用于搜索,搜索栏的重要性我们就不说了,狼厂就是靠搜索起家的,现在越来越像一匹没有节操的狼,UC浏览器搜索栏现在默认自家的神马搜索,现在不管是社 ...
- iOS - UISearchController
前言 NS_CLASS_DEPRECATED_IOS(3_0, 8_0, "UISearchDisplayController has been replaced with UISearch ...
- iOS中的两种搜索方式UISearchDisplayController和UISearchController
大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请多提意见,如果觉得不错请多多支持点赞.谢谢! hopy ;) 以前iOS的搜索一般都使用UISearchDisplayCon ...
- 搜索框UISearchController的使用(iOS8.0以后替代UISearchBar + UISearchDisplayController)
1.searchResultsUpdater:设置显示搜索结果的控制器 ? 1 _mySearchController.searchResultsUpdater = self; 2.dimsB ...
- iOS UISearchController的使用
在iOS9中,UISearchDisplayController 已经被UISearchController替代.搜索框是一种常用的控件. 假设我们要满足下图的需求,产生100个“数字+三个随机字母” ...
- iOS之搜索框UISearchController的使用(iOS8.0以后替代UISearchBar+display)
在iOS 8.0以上版本中, 我们可以使用UISearchController来非常方便地在UITableView中添加搜索框. 而在之前版本中, 我们还是必须使用UISearchBar + UISe ...
- UISearchController使用
iOS8之前我们使用UISearchDisplayController做TableView的本地搜索 iOS8提供实现搜索功能的SDK:UISearchController(iOS8.0之后).UIS ...
- UISearchController
搜索框UISearchController的使用(iOS8.0以后替代UISearchBar + UIS) 1.在iOS 8.0以上版本中, 我们可以使用UISearchController来非常方便 ...
- iOS原生的搜索:UISearchController
iOS8之前我们使用UISearchDisplayController做TableView的本地搜索,查看UIKit库,苹果已经使用新控件取代它. NS_CLASS_DEPRECATED_IOS(3_ ...
随机推荐
- 一步一步学习Vue(十三)
最近比较忙,忙着工作交接,忙着招人.忙着各种会,更新很少,这一篇也是作为本入门系列的最后一篇了,以后可能会写一些自己在前端这块的心得或者体会了,无关乎使用什么框架,可能就是原生的js.dom.编程模式 ...
- 手写简单的jq雪花飘落
闲来无事,准备写个雪花飘落的效果,没有写太牛逼的特效,极大的简化了代码量,这样容易读取代码,用起来也很简单,对于那些小白简直是福利啊,简单易读易学.先直接上代码吧,然后再一一讲解,直接复制粘贴就可以拿 ...
- 实验吧_拐弯抹角(url伪静态)&Forms
拐弯抹角 先贴代码 <?php // code by SEC@USTC echo '<html><head><meta http-equiv="chars ...
- Python3玩转儿 机器学习(2)
机器学习的基本任务 分类任务 回归任务 分类任务 手写输入数字识别 分类任务: 二分类任务 判断邮件是垃圾邮件或者不是垃圾邮件 判断发放给客户信用卡有风险或者没有风险 判断病患良性肿瘤还是恶性肿瘤 判 ...
- Words to Use Instead of "Very"
- [POI 2004]ZAW
Description 在 Byte 山的山脚下有一个洞穴入口. 这个洞穴由复杂的洞室经过隧道连接构成. 洞穴的入口是 1 号点.两个洞室要么就通过隧道连接起来,要么就经过若干隧道间接的相连. 现在决 ...
- hdu 5534(dp)
Input The first line contains an integer T indicating the total number of test cases. Each test case ...
- [BZOJ]1045 圆上的整点(HAOI2008)
数学题第二弹! Description 求一个给定的圆(x^2+y^2=r^2),在圆周上有多少个点的坐标是整数. Input 一个正整数r. Output 整点个数. Sample Input 4 ...
- OSX 鼠标和键盘事件
本文转自:http://www.macdev.io/ebook/event.html 事件分发过程 OSX 与用户交互的主要外设是鼠标,键盘.鼠标键盘的活动会产生底层系统事件.这个事件首先传递到IOK ...
- webservice服务器端获取request对象的三种方式
有的时候在webservice里我们需要获取request对象和response对象,比如想要获得客户端的访问ip的时候就需要这么做,下面说三种方式,当然三种方式可能是针对不同方式部署webservi ...