我可以挂钩进入UISearchBar Clear Button吗?

时间:2009-05-29 09:48:19

标签: iphone objective-c uikit uisearchbar

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

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

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

我注意到的一件事是文档解释了委托方法:

- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText;
点击清除按钮后调用

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

这有两个问题:

首先,由于某些原因我无法理解,即使我在我的方法结束时告诉搜索栏resignFirstResponder,某些东西,某处将其设置回到firstFirstResponder。真烦人......

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

任何正确方向的建议或指示都会很棒!

谢谢!

9 个答案:

答案 0 :(得分:17)

找到解决此问题的更好方法:)

- (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];   
}

答案 1 :(得分:11)

接受的答案是错误的。这可以做到,我只想出来并将其发布在另一个问题中:

UISearchbar clearButton forces the keyboard to appear

最佳

答案 2 :(得分:7)

我的应用程序中有这个代码。区别在于我不支持“实时搜索”,而是在用户触摸键盘上的搜索按钮时开始搜索:

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

答案 3 :(得分:7)

Swift版本处理关闭键盘上的清除按钮点击:

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

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

答案 4 :(得分:1)

我建议使用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.

因此,您可能还需要禁用原始的清除按钮。

答案 5 :(得分:1)

由于这是第一次出现,而且我可以看到问题没有得到充分解决,我想我会发布我的解决方案。

1)您需要获取searchBar中textField的引用 2)你需要在它触发时捕捉到textField的清晰。

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

a)确保你创建了一个类,因为你将在searchBar中使用textField的delegate方法。 b)另外,将searchBar连接到班级中的Outlet。我刚刚打电话给我的搜索栏。 c)从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,我不能保证它不会让您陷入麻烦。

答案 6 :(得分:1)

你可以试试这个:

- (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;
}

答案 7 :(得分:0)

根据我的经验,最佳解决方案是将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];

}

答案 8 :(得分:0)

无法在此处找到不使用私有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上被清除。