37

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

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

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

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

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

在点击清除按钮后调用。

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

这虽然有两个问题:

首先,由于某种原因,我无法理解,即使我告诉搜索栏在我的方法结束时 resignFirstResponder,某些地方正在将其设置回 becomeFirstResponder。真的很烦...

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

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

谢谢!

4

9 回答 9

18

为这个问题找到了更好的解决方案:)

- (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];   
}
于 2014-04-08T21:12:42.393 回答
12

被接受的答案是不正确的。这是可以做到的,我只是想通了,并在另一个问题中发布了它:

UISearchbar clearButton 强制键盘出现

最好的

于 2010-10-04T02:38:19.100 回答
7

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

- (void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar {
    if ([searchBar.text isEqualToString:@""]) {
        //Clear stuff here
    }
}
于 2010-02-10T13:19:30.590 回答
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()
}
于 2015-11-25T12:15:40.230 回答
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.

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

于 2010-01-26T07:47:03.893 回答
1

由于这是首先出现的,而且据我所知,这个问题并没有得到充分解决,我想我会发布我的解决方案。

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

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

a) 确保将您的类设为 a ,因为您将在 searchBar 中使用 textField 的委托方法。b) 另外,将您的 searchBar 连接到您班级中的 Outlet。我刚刚打电话给我的searchBar。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 我不能保证它不会给您带来麻烦。

于 2013-12-13T23:00:26.503 回答
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;
}
于 2014-05-23T09:54:31.357 回答
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];

}
于 2014-03-10T12:17:46.710 回答
0

在 Apple 更改 UISearchBar 的视图结构时,无法在此处找到不使用私有 API 或不升级证明的解决方案。这是我写的有效的:

- (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 上被清除调用。

于 2014-10-03T13:44:33.870 回答