最近由于優(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,說多了都是淚-------混編