随着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. [LeetCode] Range Addition II 范围相加之二

    Given an m * n matrix M initialized with all 0's and several update operations. Operations are repre ...

  2. win10+ ubuntu12.04双系统安装教程与遇到的问题

    1. 准备ISO. 参考:网站http://mirrors.ustc.edu.cn/ubuntu-releases/precise/ 下载 ubuntu-12.04.5-desktop-amd64.i ...

  3. StandardContext

    错误信息: 2014-2-6 21:37:19 org.apache.catalina.startup.HostConfig checkResources信息: Reloading context [ ...

  4. [Wc2010]重建计划

    Description Input 第一行包含一个正整数N,表示X国的城市个数. 第二行包含两个正整数L和U,表示政策要求的第一期重建方案中修建道路数的上下限 接下来的N-1行描述重建小组的原有方案, ...

  5. [Sdoi2009]Elaxia的路线

    Description 最近,Elaxia和w**的关系特别好,他们很想整天在一起,但是大学的学习太紧张了,他们 必须合理地安排两个人在一起的时间.Elaxia和w**每天都要奔波于宿舍和实验室之间, ...

  6. 计蒜客NOIP2017提高组模拟赛(五)day1-机智的 AmyZhi

    传送门 很水的题目啦QAQ #include<cstdio> #include<cstdlib> #include<algorithm> #include<c ...

  7. 【BZOJ1016】【JSOI2008】最小生成树计数

    Description 现在给出了一个简单无向加权图.你不满足于求出这个图的最小生成树,而希望知道这个图中有多少个不同的最小生成树.(如果两颗最小生成树中至少有一条边不同,则这两个最小生成树就是不同的 ...

  8. ●hihocoder #1394 网络流四·最小路径覆盖

    题链: http://hihocoder.com/problemset/problem/1394 题解: 有向图最小路径覆盖:最少的路径条数不重不漏的覆盖所有点. 注意到在任意一个最小路径覆盖的方案下 ...

  9. [hdu4694]Important Sisters

    来自FallDream的博客,未经允许,请勿转载,谢谢. 给定一张图,求每个点到第n个点必须经过的点的编号之和.n<=50000 一道支配树裸题 然后统计答案的时候可以正着推,ans[i]=an ...

  10. Java 8 的时间日期 API

    上一篇文章『Java 的时间日期 API』中,我们学习了由 Date.Calendar,DateFormat 等组成的「传统时间日期 API」,但是传统的处理接口设计并不是很友好,不易使用.终于,Ja ...