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_ ...
随机推荐
- [LeetCode] Poor Pigs 可怜的猪
There are 1000 buckets, one and only one of them contains poison, the rest are filled with water. Th ...
- [LeetCode] Path Sum IV 二叉树的路径和之四
If the depth of a tree is smaller than 5, then this tree can be represented by a list of three-digit ...
- [NOIp 2016]天天爱跑步
Description 小C同学认为跑步非常有趣,于是决定制作一款叫做<天天爱跑步>的游戏.<天天爱跑步>是一个养成类游戏,需要玩家每天按时上线,完成打卡任务. 这个游戏的地图 ...
- 计蒜客NOIP模拟赛(3)D1T3 任性的国王
X 国的地图可以被看作一个两行 nn 列的网格状图.现在 X 国需要修建铁路,然而该国的国王非常小气,他只想保证位于某两列之间的所有城市互相可以到达就行了,在此基础上,他希望所花费的代价最小. 铁路可 ...
- UVA 12161 Ironman Race in Treeland
题目大意: 每一条边都有两个权值,val和路径长度d,要保证在val<=m 的条件下,求最长的d. 解题报告: 一开始想错了,后来发现还不如直接暴力点分,思想很套路.. 平时我们统计时,都会用合 ...
- 【Codeforces AIM Tech Round 4 (Div. 2) C】
·将排序限制于子序列中,又可以说明什么呢? C. Sorting by Subsequences ·英文题,述大意: 输入一个长度为n的无重复元素的序列{a1,a2……an}(1<= ...
- hdu3487 splay树
Play with Chain Time Limit: 6000/2000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) ...
- hdu 5600 BestCoder Round #67 (div.2)
N bulbs Accepts: 275 Submissions: 1237 Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 655 ...
- solr6.6初探之分词篇
关于solr6.6搭建与配置可以参考 solr6.6初探之配置篇 在这里我们探讨一下分词的配置 一.关于分词 1.分词是指将一个中文词语拆成若干个词,提供搜索引擎进行查找,比如说:北京大学 是一个词那 ...
- SQL Server 2008 维护计划实现数据库备份(最佳实践)
一.背景 之前写过一篇关于备份的文章:SQL Server 维护计划实现数据库备份,上面文章使用完整备份和差异备份基本上能解决数据库备份的问题,但是为了保障数据更加安全,我们需要再次完善我们的备份计划 ...