前言
NS_CLASS_AVAILABLE_IOS(8_0) @interface UISearchController : UIViewController <UIViewControllerTransitioningDelegate, UIViewControllerAnimatedTransitioning>
UISearchController 继承 UIViewController,iOS 8.0 版本以后使用;iOS 8.0 之前版本可以使用 UISearchDisplayController 代替。下面着重介绍 UISearchController 基本使用,及一些经常遇到的坑,忍不住吐槽下!
1. 基本使用
1)初始化,准守协议;
- (UISearchController *)searchController {
if (!_searchController) {
_searchController = [[UISearchController alloc] initWithSearchResultsController:nil];
_searchController.searchResultsUpdater = self;
_searchController.searchBar.delegate = self;
_searchController.dimsBackgroundDuringPresentation = NO;
_searchController.hidesNavigationBarDuringPresentation = YES;
_searchController.searchBar.placeholder = @"搜索文件";
[_searchController.searchBar sizeToFit];
_searchController.searchBar.backgroundColor = [UIColor greenColor];
_searchController.searchBar.searchBarStyle = UISearchBarStyleMinimal;
_searchController.searchBar.autocorrectionType = UITextAutocorrectionTypeNo;//关闭提示
_searchController.searchBar.autocapitalizationType = UITextAutocapitalizationTypeNone;//关闭自动首字母大写
}
return _searchController;
}
- (UITableView *)tableView {
if (!_tableView) {
_tableView = [[UITableView alloc] initWithFrame:self.view.bounds style:UITableViewStylePlain];
_tableView.delegate = self;
_tableView.dataSource = self;
_tableView.tableHeaderView = self.tableHeaderView;
_tableView.tableFooterView = [UIView new];
[_tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:@"CellIdentifier"];
[self.view addSubview:_tableView];
}
return _tableView;
}
- (UIView *)tableHeaderView {
if (!_tableHeaderView) {
CGFloat height = 44.0f;
if (@available(iOS 11.0, *)) {
height = 56.0f;
}
_tableHeaderView = [[UIView alloc]initWithFrame:CGRectMake(0, 0, SCREEN_WIDTH, height)];
_tableHeaderView.backgroundColor = [UIColor whiteColor];
[_tableHeaderView addSubview:self.searchController.searchBar];
}
return _tableHeaderView;
}
2)实现 UISearchResultsUpdating 协议;
#pragma mark - UISearchResultsUpdating
- (void)updateSearchResultsForSearchController:(UISearchController *)searchController {
[self.searchResult removeAllObjects];
NSString *searchText = searchController.searchBar.text;
if ([searchText isEqualToString:@""] || searchText.length == 0) {
[self.tableView reloadData];
return;
}
dispatch_async(dispatch_get_global_queue(0, 0), ^{
for (NSString *dataStr in self.dataList) {
if ([dataStr rangeOfString:searchText].location != NSNotFound) {
[self.searchResult addObject:dataStr];
}
}
dispatch_async(dispatch_get_main_queue(), ^{
[self.tableView reloadData];
});
});
}
3)数据展示;
#pragma mark - Table view data source
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return self.searchController.isActive ? self.searchResult.count : self.dataList.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"CellIdentifier"];
NSString *dataStr = self.searchController.isActive ? self.searchResult[indexPath.row] : self.dataList[indexPath.row];
cell.textLabel.text = dataStr;
return cell;
}
2. 经常遇到的坑点
1)iOS 8 searchBar 显示空白,合适地点儿加上 sizeToFit 就好了;
[_searchController.searchBar sizeToFit];
2)侧滑返回或者点击搜索结果跳转详情页,搜索框不消失;iOS 11 isActive 状态下取消搜索,搜索框跳动;合适地点儿加上以下代码就解决了;
self.definesPresentationContext = YES;
3)iOS 11 isActive 状态下侧滑一半,搜索框消失了,我也没有好的解决方案,如果大家有好的解决方案分享学习下;我的解决方案是实现 UISearchBarDelegate,搜索状态下禁用侧滑手势,正常状态解除禁用的侧滑手势,在此禁用手势引用了 FDFullscreenPopGesture ;
#pragma mark - UISearchBarDelegate
- (void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar {
// 禁用侧滑手势,防止 iOS 11 isActive 状态下侧滑一半,搜索框消失了
self.navigationController.fd_fullscreenPopGestureRecognizer.enabled = NO;
}
- (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar {
self.navigationController.fd_fullscreenPopGestureRecognizer.enabled = YES;
}
Tip:
1)实现 UIScrollViewDelegate 协议,滑动搜索结果列表展示更友好;
#pragma mark - UIScrollViewDelegate
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView {
if (scrollView == self.tableView) {
[self.searchController.searchBar endEditing:YES];
}
}
2)重写 viewDidLayoutSubviews 方法,修改 tableView frame,解决搜索结果列表滑动到状态栏下或者 tabbar 区域透明显示;此处只适配了状态栏,iPhone X 底部 tabbar 没适配,自己修改;
- (void)viewDidLayoutSubviews {
if (self.searchController.active) {
[self.tableView mas_remakeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(self.view).offset(StatusBarHeight);
make.left.bottom.right.equalTo(self.view);
}];
}
else {
[self.tableView mas_remakeConstraints:^(MASConstraintMaker *make) {
make.top.left.bottom.right.equalTo(self.view);
}];
}
}
大家可以参考下我写的 Demo:Learn_UISearchController,具体 searchBar 样式修改大家可以上网上自行搜索,如果有什么写的不正确的地方,请指出,我会尽快修改!
网友评论