美文网首页
UISearchController 踩坑记

UISearchController 踩坑记

作者: 北漂蚂蚁 | 来源:发表于2018-07-17 17:48 被阅读0次

    前言

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

    相关文章

      网友评论

          本文标题:UISearchController 踩坑记

          本文链接:https://www.haomeiwen.com/subject/ddqgpftx.html