最近做搜索的時候使用了UISearchController遇到以下的問題:
先說說大概實現(xiàn):可以對tableView上的數(shù)據(jù)進(jìn)行搜索邮利,并在原有的tableView上顯示出搜索結(jié)果馋吗。tableViewCell是可以點擊的,并且進(jìn)行界面的切換夜畴。
問題一:
點擊SearchBar進(jìn)入了編輯狀態(tài)時,再點擊顯示出來的cell删壮,跳轉(zhuǎn)頁面時searchBar并沒有跟著view向左滑動贪绘,而是停留在原來的位置,如圖一央碟。
原因:
UISearchController也是繼承自UIViewController的税灌,也就是說UISearchController也有一個自己的View。但是在使用時只把他的searchBar顯示在表頭而沒有把自帶的view添加到self.view上,就是未指定哪一個controller顯示UISearchController上的自帶的View垄琐。所以searchBar不會跟著一起移動边酒。
解決方案:在UIViewController中有以下這個屬性
/*
Determines which parent view controller's view should be presented over for presentations of type
UIModalPresentationCurrentContext. If no ancestor view controller has this flag set, then the presenter
will be the root view controller.
*/
@property(nonatomic,assign) BOOL definesPresentationContext NS_AVAILABLE_IOS(5_0);
大概是這個屬性確定了那個父控制器的View,將會以優(yōu)先于UIModalPresentationCurrentContext這種呈現(xiàn)方式來展現(xiàn)自己的View狸窘。如果沒有父控制器設(shè)置這一屬性墩朦,那么展示的控制器將會是root view controller。
我們需要將上面那個屬性設(shè)置YES翻擒,告訴系統(tǒng)我們需要將UISearchControoller展示到當(dāng)前的tableViewController上氓涣。
修改代碼:
- (void)loadSearchController {
_searchController = [[UISearchController alloc] initWithSearchResultsController:nil];
_searchController.searchResultsUpdater = self;
_searchController.delegate = self;
[_searchController.searchBar sizeToFit];
self.tableView.tableHeaderView = _searchController.searchBar;
_searchController.dimsBackgroundDuringPresentation = NO;
// Present 時隱藏導(dǎo)航欄 該屬性默認(rèn)也為YES
_searchController.hidesNavigationBarDuringPresentation = YES;
// 增加以下代碼
self.definesPresentationContext = YES;
}
問題二:
在沒有設(shè)置definesPresentationContext時更改NavigationBar的Translucent屬性,取消半透明效果陋气。在點擊SearchBar劳吠,SearchBar會直接彈出界面如圖一。設(shè)置了definesPresentationContext屬性為YES后巩趁,點擊SearchBar痒玩,會出現(xiàn)各種下移64的問題,如圖二和圖三议慰。
原因:
導(dǎo)航欄的NavigationBar的Translucent屬性默認(rèn)為YES就是默認(rèn)是半透明效果的蠢古,將其改為NO之后,原有的布局會發(fā)生變化别凹。彈出界面的原因是沒有告訴系統(tǒng)我的SearchBarController是放在當(dāng)前控制器中的草讶,加上取消半透明后界面原有的約束發(fā)生了變化,所以searchBar就彈走了炉菲,其實就是向上多偏移了64堕战。第二種情況的是沒有設(shè)置好tableView的contentInset所導(dǎo)致的。
解決方法:
首先像第一個問題一樣加上“self.definesPresentationContext = YES;”拍霜,確保UISearchController是展示在當(dāng)前的UITableViewController上的嘱丢。在設(shè)置tableView的contentInset屬性時,一開始采用的是單純的“self.tableView.contentInset = UIEdgeInsetsZero;”祠饺,就單單這樣寫還是有問題的屿讽,在searchBar成為第一響應(yīng)者的時候,會發(fā)現(xiàn)tableView的位置比你預(yù)期的位置向上偏移了20個像素吠裆,如圖四。
20個像素烂完,這不就是狀態(tài)欄搞的鬼嗎试疙,所以在搜索狀態(tài)的時候tableView應(yīng)該向下偏移20個像素點。判斷是否是處于搜索狀態(tài)可以用UISearchController的active屬性抠蚣。我們也可以把這段代碼放在viewWillLayoutSubviews中祝旷,畢竟是要按照不同的情況設(shè)置不同的contentInset,系統(tǒng)在布局子控件的時候也會調(diào)用這個方法(必須要先super一下)。
增加代碼:
- (void)viewWillLayoutSubviews {
[super viewWillLayoutSubviews];
if (self.searchController.isActive) {
self.tableView.contentInset = UIEdgeInsetsMake(20, 0, 0, 0);
} else {
self.tableView.contentInset = UIEdgeInsetsZero;
}
}
總結(jié):
上面的內(nèi)容看起來或許有點混亂怀跛,這里基本是有關(guān)布局的問題距贷。
解決的方法都圍繞著“self.definesPresentationContext = YES;”(present控制器展示在當(dāng)前控制器而非默認(rèn)的根控制器)。將導(dǎo)航條半透明屬性設(shè)為NO之后吻谋,將會系統(tǒng)原有的布局忠蝗,想達(dá)到自己的期望需要修改“self.tableView.contentInset”。其實漓拾,這種方法解決的不是很好阁最,在動畫的時候會感覺出contentInset的變化導(dǎo)致tableView瞬移,仔細(xì)看是有一瞬間不足骇两,如果讀者有什么辦法可以解決此問題速种,可以在評論處提一下。(??????)??