UISearchBar作为inputAccessoryView时的响应链

来源:互联网 发布:淘宝买dota2饰品流程 编辑:程序博客网 时间:2024/05/01 23:21

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];// 是否显示取消按钮

        //[_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承认,也不是网上看到的文字,纯属个人猜想。

    

}

 

 

 

0 0