UISearchBar作為inputAccessoryView時的響應鏈
UISearchBar對象做為一個普通的視圖對象加入到視圖控制器的self.view中,定義、初始化、設置delegate。然後becomeFirstResponder,最後resignFirstResponder。
CGRect searchBarFrame= CGRectMake(0, 0, self.view.frame.size.width, 40);
_searchBar = [[UISearchBar alloc] initWithFrame:searchBarFrame];
[_searchBar setPlaceholder:@"Search"];// 搜索框的占位符
//[_searchBarsetPrompt:@"Prompt"];// 頂部提示文本,相當於控件的Title
[_searchBar setBarStyle:UIBarStyleDefault];// 搜索框樣式
[_searchBar setTintColor:[UIColor blueColor]];// 搜索框的顏色。當設置此屬性時,barStyle將失效
[_searchBar setTranslucent:YES];// 設置是否透明
//[_searchBarsetShowsCancelButton:YES];// 是否顯示取消button
//[_searchBarsetShowsCancelButton:YES animated:YES];
_searchBar.delegate=self;
[self.view addSubView:_searchBar];
這一切非常正常,也非常自然。
可是,這裏的應用環境是將searchBar作為一個uiresponder子類的對象gridview的inputAccessoryView。
這樣他的響應鏈條就復雜了。
我開始在searchBarTextDidBeginEditing方法中將searchBar的cancelButton展現出來。然後在searchBarTextDidEndEditing方法中將cancelButton關閉。
可是。我不管在cancel操作、search操作,及觸摸虛擬鍵盤以外的點以調用視圖控制器上的touchbegin方法,來resignFirstResponder。
這三個調用方法。都能將searchBar的第一響應者resign掉,但就是不能調用searchBarShouldEndEditing。
在整個響應鏈條中,當gridview變成firstResponder時,searchBar做為inputAccessoryView出現。再觸摸searchBar的搜索框時。firstResponder發生了變化。
gridview不再是firstResponder,searchBar變成了firstResponder。再searchBar進行resignFirstResponder後。gridView又變成了firstResponder。
這個過程理解好,在應用中須要小心處理好這樣的響應鏈條的傳遞操作。
不知道是不是由於firstResponder還在,所以沒有調用作為searchBar的delegate的searchBarTextDidEndEditing方法。
將searchBar的delegate全部方法研究一下,發現還有兩個方法能夠用,能夠用來實現這樣的cancelButton隨著firstResponder變化而展現、消失。
這兩個方法是searchBarShouldEndEditing和searchBarShouldEndEditing,在firstResponder變化前都會調用這兩個方法。
在觸摸searchBar的搜索框時。searchBar就變成了firstResponder,那麽在這時。會調用searchBarShouldEndEditing。
在我們將searchBar的firstResponder身份取消時,又會調用searchBarShouldEndEditing。
那麽。我們能夠在這兩個方法中實現我們要的功能。
結論。關鍵是理解整個響應鏈條。
在視圖控制器類中,gridview首先變成firstResponder。再searchBar變成firstResponder。
然後逐步resignFirstResponder,即使在self.view endEditing。也逐步操作。
代碼
-(void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar
{
//無法調用 cancelbuttong 的 關閉功能, 妥協 不用這個吧。
// [_searchBarsetShowsCancelButton:YES animated:YES];
// 發現放到searchBarShouldBeginEditing 方法中也能實現這個功能,
// 在方法searchBarShouldEndEditing 中能夠 將 cancelbutton 關閉掉。
}
-(BOOL)searchBarShouldBeginEditing:(UISearchBar *)searchBar
{
[_searchBar setShowsCancelButton:YES animated:YES];
BOOL xx,yy;
xx=[_gridView isFirstResponder];
yy=[_searchBar isFirstResponder];
NSLog(@"_gridView,searchBar %d,%d",xx,yy);
return YES;
}
-(BOOL)searchBarShouldEndEditing:(UISearchBar *)searchBar
{
[_searchBar setShowsCancelButton:NO animated:YES];
BOOL xx,yy;
xx=[_gridView isFirstResponder];
yy=[_searchBar isFirstResponder];
NSLog(@"_gridView,searchBar %d,%d",xx,yy);
return YES;
}
-(void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar
{
//無法調用 cancelbuttong 的 關閉功能, 妥協 不用這個吧。
// [_searchBarsetShowsCancelButton:YES animated:YES];
// 發現放到searchBarShouldBeginEditing 方法中也能實現這個功能。
// 在方法searchBarShouldEndEditing 中能夠 將 cancelbutton 關閉掉。
}
-(void)searchBarTextDidEndEditing:(UISearchBar *)searchBar
{
// 這種方法還是不能被調用。無法解釋。
// [_searchBar setShowsCancelButton:NO animated:YES];
}
-(void)searchBarSearchButtonClicked:(UISearchBar *)searchBar
{
[_searchBar resignFirstResponder];
}
-(void)searchBarCancelButtonClicked:(UISearchBar *)searchBar
{
BOOL xx,yy;
xx=[_gridView isFirstResponder];
yy=[_searchBar isFirstResponder];
NSLog(@"_gridView,searchBar %d,%d",xx,yy);
[_searchBar resignFirstResponder];
xx=[_gridView isFirstResponder];
yy=[_searchBar isFirstResponder];
NSLog(@"_gridView,searchBar %d,%d",xx,yy);
// 當 searchbar 不是 first responder時,gridview自己主動變成了 first responder.
// 所以,searchbar不會變成 end editing,它也就不會調用searchBarTextDidBeginEditing:方法。這是推測,沒理論依據,也沒得到apple承認,也不是網上看到的文字。純屬個人猜想。
}
UISearchBar作為inputAccessoryView時的響應鏈