1. 程式人生 > >UISearchBar作為inputAccessoryView時的響應鏈

UISearchBar作為inputAccessoryView時的響應鏈

不知道 方法 虛擬鍵盤 elf esp 處理 str ntc def

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時的響應鏈