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] Candy Crush 糖果消消乐
This question is about implementing a basic elimination algorithm for Candy Crush. Given a 2D intege ...
- [LeetCode] Find Mode in Binary Search Tree 找二分搜索数的众数
Given a binary search tree (BST) with duplicates, find all the mode(s) (the most frequently occurred ...
- 树莓派控制HC-SR04超声波模块测距(新手向+C语言向)
因为作业要求使用c语言代码,这里先附上一段摘自网上的代码 感谢KalaerSun的c语言代码,摘自https://blog.csdn.net/qq_25247589/article/details/6 ...
- .Net Core小技巧 - 使用Swagger上传文件
前言 随着前后端分离开发模式的普及,后端人员更多是编写服务端API接口.调用接口实现文件上传是一个常见的功能,同时也需要一个选择文件上传的界面,可以编写前端界面上传,可以使用Postman.curl来 ...
- [HNOI 2018]排列
Description 题库链接 给定 \(n\) 个整数 \(a_1, a_2, \dots, a_n, 0 \le ai \le n\) ,以及 \(n\) 个整数 \(w_1, w_2, \do ...
- k-d tree模板练习
1. [BZOJ]1941: [Sdoi2010]Hide and Seek 题目大意:给出n个二维平面上的点,一个点的权值是它到其他点的最长距离减最短距离,距离为曼哈顿距离,求最小权值.(n< ...
- hdu 5439(找规律)
The sequence is generated by the following scheme. 1. First, write down 1, 2 on a paper. 2. The 2nd ...
- 【UVA–11997 K Smallest Sums 】
·哦,这题要用优先队列?那大米饼就扔一个手写堆上去吧! ·英文题,述大意: 输入n个长度为n的序列(题中是k,2<=k<=750).一种结果定义为:从每个序列中都要挑选一个数加 ...
- day4 liaoxuefeng---面向对象编程、IO编程
一.面向对象编程 二.面向对象高级编程 三.IO编程
- Java的五子棋实现
Java 五子棋 注:除机器人算法外其余借鉴于MLDN. package MyFiveChess; import robot.*; import java.awt.*; import javax.sw ...