我可以钩入UISearchBar的清除按钮吗?

问题描述:

我的界面中有一个UISearchBar,我想定制一些文本输入后出现在搜索栏中的小清除按钮的行为(它是一个带有十字的小灰圈,出现在搜索字段的右侧)。我可以钩入UISearchBar的清除按钮吗?

基本上,我希望它不仅可以清除搜索栏(这是默认实现)的文本,还可以从我的界面清除一些其他内容,但调用我自己的方法之一。

我在UISearchBar类或UISearchBarDelegate协议的文档中找不到任何内容 - 它看起来不像您可以直接访问此行为。

有一件事我确实注意到的是,该文档解释了委托方法:

- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText; 

清除按钮被点击后调用。

我最初在该方法中编写了一些代码来检查搜索栏的文本属性,如果它是空的,那么它已被清除并执行我所有其他的操作。

两个问题。这虽然其中:

首先,由于某种原因,我无法捉摸,即使我告诉搜索栏在我的方法,一些年底resignFirstResponder,某处设置回becomeFirstResponder。真的很烦......

其次,如果用户不使用清除按钮,并且使用键盘上的删除按钮简单地删除栏中的文本,则会触发此方法并且其搜索结果消失。不好。

任何意见或指针在正确的方向将是伟大的!

谢谢!

这是公认的答案是不正确。这是可以做到的,我只是想通了,在另一个问题贴吧:

UISearchbar clearButton forces the keyboard to appear

最佳

我建议使用UITextField的rightViewrightViewMode方法创建您自己的使用相同图像的清除按钮。我假设当然UISearchBar会让你访问其中的UITextField。我认为会的。
注意这一点从iPhone OS参考库:

If an overlay view overlaps the clear button, however, the clear button always takes precedence in receiving events. By default, the right overlay view does overlap the clear button.

所以,你可能还需要禁用原来的清除按钮。

+1

我敢肯定的UISearchBar不公开它的texfield ... – Jasarien 2010-01-27 08:22:07

我已经在我的应用程序中得到了这段代码。不同的是,我不支持“Live搜索”,而是开始当用户触摸键盘上的搜索按钮搜索:

- (void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar { 
    if ([searchBar.text isEqualToString:@""]) { 
     //Clear stuff here 
    } 
} 
+0

+1我这个答案达成一致。如果文本是空的,在清除之后,它意味着清除按钮已被按下。 @Jasarien你找到了解决方案吗? – JoePasq 2010-02-13 16:36:25

+0

Surley use - (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText 而不是,否则,如果您需要在清除时退出第一响应者,用户将永远无法选择该框,因为它们在开始时将是空的。 – Marc 2013-07-19 08:34:43

因为这首先出现,而据我所看到的问题是没有真正充分解决,我想我会发布我的解决方案。

1)您需要获取对searchBar内的textField的引用。2)您需要在触发时捕获textField的清除。

这很简单。这是一种方法。

a)确保你的类是一个类,因为你将在searchBar中使用textField的委托方法。 b)另外,将你的searchBar连接到你的班级的Outlet。我只是叫我的搜索栏。 c)from viewDidLoad你想获得searchBar里面的textField的位置。我是这样做的。

UITextField *textField = [self.searchBar valueForKey:@"_searchField"]; 
if (textField) { 
    textField.delegate = self; 
    textField.tag = 1000; 
} 

请注意,我为该textField分配了一个标记,以便我可以再次抓住它,并且我将其作为textField委托。您可能已经创建了一个属性,并将该textField分配给该属性以稍后抓取它,但我使用了一个标签。

从这里你只需要调用的委托方法:

-(BOOL)textFieldShouldClear:(UITextField *)textField { 
if (textField.tag == 1000) { 
    // do something 
    return YES; 
} 
return NO; 

}

就是这样。既然你指的是一个私有的valueForKey,我不能保证它不会让你陷入困境。

+1

非常感谢你,伙计 – SampathKumar 2014-05-23 05:16:51

从我的经验

最好的解决办法就是把一个UIButton(背景清晰的和无文本)系统清除按钮上方,比连接一个IBAction为

- (IBAction)searchCancelButtonPressed:(id)sender { 

    [self.searchBar resignFirstResponder]; 
    self.searchBar.text = @""; 

    // some of my stuff 
    self.model.fastSearchText = nil; 
    [self.model fetchData]; 
    [self reloadTableViewAnimated:NO]; 

} 

找到这个问题的更好的解决办法:)

- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText{ 
    if ([searchText length] == 0) { 
     [self performSelector:@selector(hideKeyboardWithSearchBar:) withObject:searchBar afterDelay:0]; 
    } 
} 

- (void)hideKeyboardWithSearchBar:(UISearchBar *)searchBar{ 
    [searchBar resignFirstResponder]; 
} 
+0

Tnx好伎俩,我在Swift 2中添加了Swift 2版本作为回答 – ergunkocak 2015-11-25 12:13:30

你可以试试这个:

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 
    for (UIView *view in searchBar.subviews){ 
     for (UITextField *tf in view.subviews) { 
      if ([tf isKindOfClass: [UITextField class]]) { 
       tf.delegate = self; 
       break; 
      } 
     } 
    } 
} 

- (BOOL)textFieldShouldClear:(UITextField *)textField { 
    // your code 
    return YES; 
} 

无法给散热鳍片d这里没有使用私有API或者没有升级证明的解决方案Apple更改了UISearchBar的视图结构。下面是我写的作品:

- (void)viewDidLoad { 
    [super viewDidLoad]; 

    UITextField* textfield = [self findTextFieldInside:self.searchBar]; 
    [textfield setDelegate:self]; 
} 

- (UITextField*)findTextFieldInside:(id)mainView { 
    for (id view in [mainView subviews]) { 
     if ([view isKindOfClass:[UITextField class]]) { 
      return view; 
     } 

     id subview = [self findTextFieldInside:view]; 
     if (subview != nil) { 
      return subview; 
     } 
    } 

    return nil; 
} 

然后实现UITextFieldDelegate协议到类和覆盖textFieldShouldClear:方法。

- (BOOL)textFieldShouldClear:(UITextField*)textField { 
    // Put your code in here. 
    return YES; 
} 

编辑:设置在iOS8上的搜索栏会产生碰撞的文本框的委托。不过它看起来像searchBar:textDidChange:方法将在iOS8上清除。

斯威夫特版本上清除按钮点击处理接近键盘:

func searchBar(searchBar: UISearchBar, textDidChange searchText: String) { 
    if searchText.characters.count == 0 { 
     performSelector("hideKeyboardWithSearchBar:", withObject:searchBar, afterDelay:0) 
    } 
} 

func hideKeyboardWithSearchBar(bar:UISearchBar) { 
    bar.resignFirstResponder() 
}