UISearchController 踩坑记

前言

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 样式修改大家可以上网上自行搜索,如果有什么写的不正确的地方,请指出,我会尽快修改!

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 1、通过CocoaPods安装项目名称项目信息 AFNetworking网络请求组件 FMDB本地数据库组件 SD...
    阳明AGI阅读 16,018评论 3 119
  • 首先需要感谢一下cocoaChina里的一个小伙伴的demo 先下载demo再看内容,会比较爽SearchDemo...
    真爱要有你才完美阅读 1,191评论 2 1
  • 一 泓亦走进这家茶社的时候正是傍晚,因茶社开门向西,他便看到夕阳在中式方格窗上投下的调皮碎影,碎影的地方是一...
    花落寂寂hjr阅读 421评论 9 2
  • “记不住了,你现在在哪儿上班?” “受了学姐你很大的影响,我现在是一名律师。”男孩儿羞涩地挠挠头。 “不错啊!” ...
    Celloqt阅读 571评论 0 1
  • 专注的魅力 爸爸每次去理发,总是到同一个理发店。理发店离我家很远,徒步都要走二公里。 我们家楼下...
    白小洋阅读 206评论 0 1