随着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];
}

然后,还必须实现的UISearchControllerUISearchResultsUpdating中的代理方法:

- (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的更多相关文章

  1. iOS--- UITableView + UISearchDisplayController - - - - -实现搜索功能

    iOS中UISearchDisplayController用于搜索,搜索栏的重要性我们就不说了,狼厂就是靠搜索起家的,现在越来越像一匹没有节操的狼,UC浏览器搜索栏现在默认自家的神马搜索,现在不管是社 ...

  2. iOS - UISearchController

    前言 NS_CLASS_DEPRECATED_IOS(3_0, 8_0, "UISearchDisplayController has been replaced with UISearch ...

  3. iOS中的两种搜索方式UISearchDisplayController和UISearchController

    大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请多提意见,如果觉得不错请多多支持点赞.谢谢! hopy ;) 以前iOS的搜索一般都使用UISearchDisplayCon ...

  4. 搜索框UISearchController的使用(iOS8.0以后替代UISearchBar + UISearchDisplayController)

    1.searchResultsUpdater:设置显示搜索结果的控制器 ? 1     _mySearchController.searchResultsUpdater = self; 2.dimsB ...

  5. iOS UISearchController的使用

    在iOS9中,UISearchDisplayController 已经被UISearchController替代.搜索框是一种常用的控件. 假设我们要满足下图的需求,产生100个“数字+三个随机字母” ...

  6. iOS之搜索框UISearchController的使用(iOS8.0以后替代UISearchBar+display)

    在iOS 8.0以上版本中, 我们可以使用UISearchController来非常方便地在UITableView中添加搜索框. 而在之前版本中, 我们还是必须使用UISearchBar + UISe ...

  7. UISearchController使用

    iOS8之前我们使用UISearchDisplayController做TableView的本地搜索 iOS8提供实现搜索功能的SDK:UISearchController(iOS8.0之后).UIS ...

  8. UISearchController

    搜索框UISearchController的使用(iOS8.0以后替代UISearchBar + UIS) 1.在iOS 8.0以上版本中, 我们可以使用UISearchController来非常方便 ...

  9. iOS原生的搜索:UISearchController

    iOS8之前我们使用UISearchDisplayController做TableView的本地搜索,查看UIKit库,苹果已经使用新控件取代它. NS_CLASS_DEPRECATED_IOS(3_ ...

随机推荐

  1. [HNOI 2009]最小圈

    Description 考虑带权的有向图$G=(V,E)$以及$w:E\rightarrow R$,每条边$e=(i,j)(i\neq j,i\in V,j\in V)$的权值定义为$w_{i,j}$ ...

  2. HDU3311Dig The Wells

    给定N个寺庙,和M个另外的地方. 然后给定点权,表示在这个点挖水井需要的代价. 再给定边权,为建造无向边i,j的代价. 然后求怎样弄最小的代价使得前N个点,就是寺庙都能从挖的井里得到水. 输入输出格式 ...

  3. 【数据结构】【平衡树】无旋转treap

    最近在研究平衡树,看起来这种东西又丧水又很深,感觉很难搞清楚.在Ditoly学长的建议下,我先学习了正常的treap,个人感觉这应该是平衡树当中比较好懂的而且比较好写的一种. 然而,发现带旋treap ...

  4. 【NOIP 2017】宝藏

    Description 参与考古挖掘的小明得到了一份藏宝图,藏宝图上标出了 n 个深埋在地下的宝藏屋, 也给出了这 n 个宝藏屋之间可供开发的 m 条道路和它们的长度. 小明决心亲自前往挖掘所有宝藏屋 ...

  5. [Baltic2004]sequence

    题目描述: 给定一个序列t1,t2,...,tn ,求一个递增序列z1<z2<...<zn , 使得R=|t1−z1|+|t2−z2|+...+|tn−zn| 的值最小.本题中,我们 ...

  6. 网络编程基础API

    1.预备知识 网络字节序 1.TCP/IP协议规定,网络数据流应采用大端字节序 0x12345678 小端存储:78存储在低地址 大端存储:12存储在低地址 网络字节序和主机字节序的转换 #inclu ...

  7. poj 2065 高斯消元(取模的方程组)

    SETI Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 1735   Accepted: 1085 Description ...

  8. [Codeforces]849E Goodbye Souvenir

    又是一道比较新的模板题吧,即使是在Codeforces上小C还是贴了出来. Description 给定一个长度为n的序列a1~an,每个元素代表一种颜色.m次操作,每次操作为两种中的一种: 1 p ...

  9. Codeforces Round #430 B. Gleb And Pizza

    Gleb ordered pizza home. When the courier delivered the pizza, he was very upset, because several pi ...

  10. Python使用wmi获取Windows相关信息

    在使用Python获取Windows系统上的相关的信息可以使用WMI接口来获取, 什么是wmi? WMI是一项核心的Windows管理技术,WMI作为一种规范和基础结构,通过它可以访问.配置.管理和监 ...