objective-c 我可以连接到 UISearchBar 的清除按钮吗?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/925221/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-03 21:37:43  来源:igfitidea点击:

Can I hook into UISearchBar's Clear Button?

iphoneobjective-cuikituisearchbar

提问by Jasarien

I've got a UISearchBar in my interface and I want to customise the behaviour of the the small clear button that appears in the search bar after some text has been entered (it's a small grey circle with a cross in it, appears on the right side of the search field).

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

Basically, I want it to not only clear the text of the search bar (which is the default implementation) but to also clear some other stuff from my interface, but calling one of my own methods.

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

I can't find anything in the docs for the UISearchBar class or the UISearchBarDelegate protocol - it doesn't look like you can directly get access to this behaviour.

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

The one thing I did note was that the docs explained that the delegate method:

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

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

is called after the clear button is tapped.

在点击清除按钮后调用。

I initially wrote some code in that method that checked the search bar's text property, and if it was empty, then it had been cleared and to do all my other stuff.

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

Two problems which this though:

这虽然有两个问题:

Firstly, for some reason I cannot fathom, even though I tell the search bar to resignFirstResponder at the end of my method, something, somewhere is setting it back to becomeFirstResponder. Really annoying...

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

Secondly, if the user doesn't use the clear button, and simply deletes the text in the bar using the delete button on the keyboard, this method is fired off and their search results go away. Not good.

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

Any advice or pointers in the right direction would be great!

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

Thanks!

谢谢!

采纳答案by boliva

The answer which was accepted is incorrect. This can be done, I just figured it out and posted it in another question:

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

UISearchbar clearButton forces the keyboard to appear

UISearchbar clearButton 强制键盘出现

Best

最好的事物

回答by Waqas Haider Sheikh

Found the better solution for this problem :)

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

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

回答by Rengers

I've got this code in my app. Difference is that I don't support 'live search', but instead start searching when the user touches the search button on the keyboard:

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

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

回答by ergunkocak

Swift version handling close keyboard on clear button click :

单击清除按钮时 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()
}

回答by Denis Redis

You could try this:

你可以试试这个:

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

回答by smileBot

Since this comes up first, and far as I can see the question wasn't really adequately addressed, I thought I'd post my solution.

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

1) You need to get a reference to the textField inside the searchBar 2) You need to catch that textField's clear when it fires.

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

This is pretty simple. Here's one way.

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

a) Make sure you make your class a , since you will be using the delegate method of the textField inside the searchBar. b) Also, connect your searchBar to an Outlet in your class. I just called mine searchBar. c) from viewDidLoad you want to get ahold of the textField inside the searchBar. I did it like this.

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

Notice, I assigned a tag to that textField so that I can grab it again, and I made it a textField delegate. You could have created a property and assigned this textField to that property to grab it later, but I used a tag.

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

From here you just need to call the delegate method:

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

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

}

}

That's it. Since you are referring to a private valueForKey I can't guarantee that it will not get you into trouble.

就是这样。由于您指的是私有 valueForKey,因此我不能保证它不会给您带来麻烦。

回答by Andrew

I would suggest using the rightViewand rightViewModemethods of UITextField to create your own clear button that uses the same image. I'm assuming of course that UISearchBar will let you access the UITextField within it. I think it will.
Be aware of this from the iPhone OS Reference Library:

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

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.

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.

So you'll probably also need to disable the original clear button.

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

回答by Peter Lapisu

Best solution from my experience is just to put a UIButton (with clear background and no text) above the system clear button and than connect an IBAction

根据我的经验,最好的解决方案是在系统清除按钮上方放置一个 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];

}

回答by Nichole Mattera

Wasn't able to find a solution here that didn't use a private API or wasn't upgrade proof incase Apple changes the view structure of the UISearchBar. Here is what I wrote that works:

无法在这里找到不使用私有 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;
}

Then implement the UITextFieldDelegate protocol into your class and overwrite the textFieldShouldClear: method.

然后在您的类中实现 UITextFieldDelegate 协议并覆盖 textFieldShouldClear: 方法。

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

Edit:Setting the delegate on the textfield of a search bar in iOS8 will produce a crash. However it looks like the searchBar:textDidChange: method will get called on iOS8 on clear.

编辑:在 iOS8 中搜索栏的文本字段上设置委托会导致崩溃。但是看起来 searchBar:textDidChange: 方法会在 iOS8 上被调用。