UISearchController踩坑奇遇記

最近由于優(yōu)化搜索功能,要把之前工程內(nèi)廢棄的UISearchDisplayController換成UISearchController,總結(jié)下期間遇到的一些問題,便于以后查找,分享出來讓大家少踩坑。

使用方法

1.創(chuàng)建

建議如下設(shè)置ViewController和tableView,手動(dòng)管理tableView偏移

    if (@available(iOS 11.0, *)) {
        _tableView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
    }
    self.edgesForExtendedLayout = UIRectEdgeNone;
    self.automaticallyAdjustsScrollViewInsets = NO;
    self.definesPresentationContext = YES;//不設(shè)置會(huì)導(dǎo)致一些位置錯(cuò)亂,無動(dòng)畫等問題

創(chuàng)建UISearchController

- (UISearchController *)searchController {
    if (!_searchController) {
        //創(chuàng)建方法,如果在當(dāng)前控制器顯示,傳nil
        _searchController = [[UISearchController alloc] initWithSearchResultsController:nil];
        //結(jié)果代理回調(diào)
        _searchController.searchResultsUpdater = self;
        //可選,searchBar的代理回調(diào)
        //_searchController.searchBar.delegate = self;
        //可選,回調(diào)SearchController的顯示退出等
        //_searchController.delegate = self;
        //active狀態(tài)是否顯示一個(gè)半透明的覆蓋層
        if (@available(iOS 9.1, *)) {
            _searchController.obscuresBackgroundDuringPresentation = NO;
        }
        _searchController.dimsBackgroundDuringPresentation = NO;
        //active狀態(tài)是否隱藏navigationBar,默認(rèn)為YES
        _searchController.hidesNavigationBarDuringPresentation = NO;
    }
    return _searchController;
}

2.UI顯示

  • 作為UITableView的tableHeaderView

  •   self.tablView.tableHeaderView = self.searchController.searchBar;
    
  • 添加到UINavigationBar

  •   self.navigationItem.titleView = self.searchController.searchBar;
    
  • 添加到其它view

  •   [self.view addSubview:self.searchController.searchBar];
    

3.搜索數(shù)據(jù)顯示

實(shí)現(xiàn)- (void)updateSearchResultsForSearchController:(UISearchController *)searchController代理方法,需要更新數(shù)據(jù)時(shí)會(huì)回調(diào)到這個(gè)方法,然后在里面做搜索操作,最后刷新列表。

如果搜索前的數(shù)據(jù)和搜索后的數(shù)據(jù)是在一個(gè)UITablView上顯示的,在UITableView的代理回調(diào)里,可通過self.searchController.active判斷應(yīng)該顯示原數(shù)據(jù)還是搜索后的數(shù)據(jù)

自定義技巧

獲取輸入框

UITextField *textField = [searchBar valueForKey:@"_searchField"];

獲取取消按鈕

UIButton *cancelButton = [searchBar valueForKey:@"_cancelButtonText"];

總是不顯示取消按鈕

繼承UISearchBar,重寫show方法,不做任何處理

class KDSearchBar: UISearchBar {
    
    var alwaysHiddenCancelButton: Bool = false
    override func setShowsCancelButton(_ showsCancelButton: Bool, animated: Bool) {
        if !alwaysHiddenCancelButton {
            super.setShowsCancelButton(showsCancelButton, animated: animated)
        }
    }
}

繼承UISearchController,重寫SearchBar的Getter方法

class KDSearchController: UISearchController {
    
    fileprivate let reallySearchBar = KDSearchBar()
    ///總不顯示取消按鈕,默認(rèn)searchBar點(diǎn)擊時(shí)會(huì)觸發(fā)顯示
    var alwaysHiddenCancelButton: Bool = false {
        didSet {
            reallySearchBar.alwaysHiddenCancelButton = alwaysHiddenCancelButton
        }
    }
    override var searchBar: UISearchBar {
        return reallySearchBar
    }
}

自定義輸入框高度

override func layoutSubviews() {
        super.layoutSubviews()
        
        //設(shè)置textfield
        if let textField: UITextField = value(forKey: "_searchField") as? UITextField {
            var frame = textField.frame
            frame.size.height = 30
            frame.origin.y = (self.bounds.size.height - frame.size.height) / 2.0
            textField.frame = frame
            textField.layer.cornerRadius = 15
            textField.layer.masksToBounds = true
        }
}

奇遇記

iOS8問題匯總

1. updateSearchResultsForSearchController不回調(diào)

如果設(shè)置了searchBar.delegate輸入文字時(shí)不會(huì)調(diào)這個(gè)方法,只有進(jìn)入active狀態(tài)和退出active狀態(tài)的時(shí)候會(huì)回調(diào),解決辦法就是實(shí)現(xiàn)- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText回調(diào)方法進(jìn)行搜索

2.UISearchBar不顯示

在合適的地方調(diào)用[self.searchController.searchBar sizeToFit];

3.點(diǎn)擊SearchBar不能移動(dòng)到NavigationBar,點(diǎn)擊取消后回不了原始狀態(tài)

- (BOOL)searchBarShouldBeginEditing:(UISearchBar *)searchBar {
   self.searchController.active = YES; 
   return YES;
}

- (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar {
    self.searchController.active = NO; 
}

4.present一個(gè)VC后進(jìn)入active狀態(tài)點(diǎn)取消,頁面退出模態(tài)視圖了

如果主視圖是present過去的,不能設(shè)置active為NO,只能用[searchBar resignFirstResponder]代替

5.active狀態(tài)調(diào)用resignFirstResponder退出輸入狀態(tài)后點(diǎn)擊取消失效

這個(gè)時(shí)間點(diǎn)擊取消發(fā)現(xiàn)并沒有回調(diào)searchBarCancelButtonClicked而是回調(diào)到searchBarShouldBeginEditing,經(jīng)調(diào)試發(fā)現(xiàn)取消按鈕的enable值為NO,解決辦法是使用KVO監(jiān)聽這個(gè)值,然后把這個(gè)值改為YES。

6.active狀態(tài) tableview位置偏移20px

如果原數(shù)據(jù)和搜索出的數(shù)據(jù)顯示在一個(gè)列表上,在搜索狀態(tài)tableView會(huì)上移20象素解決辦法如下

- (void)didPresentSearchController:(UISearchController *)searchController {
    //防止搜索時(shí)tableview位置不對(duì)
    [_tableView remakeConstraints:^(MASConstraintMaker *make){
        make.left.right.bottom.equalTo(self.view);
        make.top.equalTo(self.view.top).with.offset(20);
    }];
}

- (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar {
    //調(diào)整frame寫到這兒是因?yàn)榻缑嫣D(zhuǎn)前先改回來,系統(tǒng)會(huì)自動(dòng)生成對(duì)應(yīng)的動(dòng)畫,不會(huì)跳得很厲害,不信你改到didDismissSearchController試試,你會(huì)回來謝謝我
    [_tableView remakeConstraints:^(MASConstraintMaker *make){
        make.edges.equalTo(self.view);
    }];
    //回滾到最初位置
    [_tableView setContentOffset:CGPointMake(0, 0)];
}

iOS11列表contentsize偶爾算不對(duì)

    _tableView.estimatedRowHeight = 0;
    _tableView.estimatedSectionHeaderHeight = 0;
    _tableView.estimatedSectionFooterHeight = 0;

不要問我為什么上面又是OC又是Swift,說多了都是淚-------混編

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • UISearchBar和UISearchDisplayController配合使用,是iOS8之前的使用方法,iO...
    花小蓉閱讀 997評(píng)論 0 2
  • 1、searchBar 本例子實(shí)現(xiàn)布局:上面是一個(gè)navigationController,接下來一個(gè)search...
    lilinjianshu閱讀 3,670評(píng)論 1 8
  • 工作了好久一直很忙,好不容易有些時(shí)間,今天有人問我如何開始寫一個(gè)項(xiàng)目,不禁回憶起自己寫第一個(gè)項(xiàng)目的時(shí)候,到現(xiàn)在,突...
    小東門兒閱讀 902評(píng)論 0 4
  • 晚上看書,發(fā)現(xiàn)自己靜不下心來,看著看著就走神,要么看時(shí)間,要么看微信,強(qiáng)制自己看了將近一小時(shí)書。 上午和顏春暉、吳...
    黃雨田閱讀 829評(píng)論 0 0
  • 又過了三個(gè)月,時(shí)間過得真快。有天,樊秀很奇怪地問張智成:“你怎么這么長(zhǎng)時(shí)間沒去看嬌嬌的奶奶?平時(shí)可是三天兩頭往...
    甜蜜果閱讀 267評(píng)論 0 1

友情鏈接更多精彩內(nèi)容