简体   繁体   English

按下键盘并轻按x时在UISearchBar上执行操作

[英]Perform action on UISearchBar when Keyboard is down and the x has been tapped

I have a UITableView with a UISearchBar on top and have a specific requirement that isn't working. 我有一个顶部带有UISearchBarUITableView ,并且有一个不起作用的特定要求。

I have no Cancel button on my UISearchBar (showsCancelButton = NO) so I rely completely on the x within the UISearchBar to cancel the existing search. 我的UISearchBar (showsCancelButton = NO)上没有取消按钮UISearchBar (showsCancelButton = NO)因此我完全依赖UISearchBar内的x来取消现有搜索。 I rely on the Keyboard's "Search" button to dismiss the keyboard (though it's called Done in my case). 我依靠键盘的“搜索”按钮关闭键盘(尽管在我的情况下称为“完成”)。

When a user searches in my app, I'm disabling a navigation bar button item because it gives a bad user experience, and only when the search has cancelled does the user get the navigation bar button item back. 当用户在我的应用程序中搜索时,我将禁用navigation bar button项,因为它给用户带来不好的体验,并且只有在搜索取消后,用户才能重新获得导航栏按钮项。 That's all working. 都可以了

I have one particular scenario though that I cannot get around. 我有一个特殊的场景,尽管我无法绕开。

1) Tap on the Search Bar to enter Text 1)点击搜索栏以输入文本

2) Click DONE on the Keyboard and the Keyboard will disappear 2)在键盘上单击“完成”,键盘将消失

3) With the keyboard resigned, the x remains in the UISearchBar 3)在键盘退回的情况下,x保留在UISearchBar

4) Tap the x in the UISearchBar and the text in the SearchBar disappears and the view refreshes 4)点击UISearchBar的x, SearchBar的文本消失,视图刷新

5) At this point, the navigation bar button should be enabled again, but it's not. 5)此时,应该再次启用导航栏按钮,但是没有启用。

Code: 码:

- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText
{
    self.timelineSearchBar.showsCancelButton = NO;
    if ([searchText length] == 0)
    {
        [self.timelineSearchBar performSelector:@selector(resignFirstResponder)
                    withObject:nil
                  afterDelay:0];
    }

I know that the code above is meant to dismiss the keyboard when the x is pressed which is fine. 我知道上面的代码旨在在按下x时关闭键盘,这很好。

In my case, the keyboard is already resigned, so I want the tapping of the x to just re-enable the navigation bar item. 就我而言,键盘已经被辞职了,因此我希望点击x即可重新启用导航栏项。

    self.addButton.enabled = YES; 

in that if statement above doesn't do anything at all and the navigation bar item is still disabled. 因为上面的if语句根本不执行任何操作,并且导航栏项仍处于禁用状态。

I've even tried in that if statement : 我什至尝试了if语句:

[self.timelineSearchBar performSelector:@selector(enableAdd)
                    withObject:nil
                  afterDelay:0];

- (void)enableAdd
{
    self.addButton.enabled = YES;
}

but that crashes saying searchBar does not respond to that enableAdd selector. 但这会崩溃,说明searchBar不响应该enableAdd选择器。

I've done a breakpoint and see that the if statement above does evaluate to true when I tap the x and it goes into the statement, it "runs" the code to enable the button, but it never happens. 我已经完成了一个断点,并且看到当我点击x时,上面的if语句的评估结果为true,它进入该语句,它“运行”代码以启用该按钮,但从未发生。

Also my end editing method is: 我的最终编辑方法是:

- (void)searchBarTextDidEndEditing:(UISearchBar *)searchBar
{
    [searchBar setShowsCancelButton:NO animated:YES];
    self.addButton.enabled = YES;
}

UPDATE: I've tried the link here http://engineeringtheworld.wordpress.com/2011/04/11/detecting-when-clear-is-clicked-in-uisearchbar-x-button/ with no success - the textField's shouldClear method doesn't get called. 更新:我已经尝试过这里的链接http://engineeringtheworld.wordpress.com/2011/04/11/detecting-when-clear-is-clicked-in-uisearchbar-x-button/没有成功-textField的shouldClear方法不会被调用。 I'm using iOS 7 so perhaps there's another way to embed the views with textFields? 我正在使用iOS 7,所以也许还有另一种方法可以将视图嵌入到textFields中? This is very possibly the right approach, but it's not working with my code because the for statement in that sample never gets evaluated as true (I put in an NSLog). 这很可能是正确的方法,但是它不适用于我的代码,因为该示例中的for语句永远不会被评估为true(我放入NSLog中)。

UPDATE 2: From if the if statement above, I called the searchBarCancelButton method and I had extreme loops being caused, so that of course wasn't the right approach: 更新2:从上面的if语句中,我调用了searchBarCancelButton方法,并且导致了极端循环,因此,这当然不是正确的方法:

[self performSelector:@selector(searchBarCancelButtonClicked:) withObject:self.timelineSearchBar afterDelay: 0];

Any guidance on this would be really appreciated. 任何对此的指导将不胜感激。 I know I'm missing a key step but I just can't quite figure it out. 我知道我错过了关键一步,但我只是想不通。

The problem is that when tapping the X button, searchBar:textDidChange: is called before searchBarShouldBeginEditing: 问题是,轻敲X按钮时, searchBar:textDidChange: 之前被称为searchBarShouldBeginEditing:

ie here is the call flow: searchBar:textDidChange: -> searchBarShouldBeginEditing: -> searchBarTextDidBeginEditing: -> searchBarTextDidEndEditing: 即,这里是调用流程: searchBar:textDidChange: -> searchBarShouldBeginEditing: -> searchBarTextDidBeginEditing: -> searchBarTextDidEndEditing:

textDidChange is setting enabled to YES, but then shouldBeginEditing is disabling it again. textDidChange的设置启用为YES,但然后shouldBeginEditing再次将其禁用。 This works perfectly for me: 这对我来说非常合适:

-(void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar
{
    self.addButton.enabled = NO;
}

-(void)searchBarTextDidEndEditing:(UISearchBar *)searchBar
{
    if(searchBar.text.length == 0){
        self.addButton.enabled = YES;
    }
}

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

-(void)searchBarSearchButtonClicked:(UISearchBar *)searchBar
{
    self.addButton.enabled = [searchBar.text length] == 0;
    [searchBar resignFirstResponder];
}
-(void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText
{
    if([searchText length] == 0 && searchBar.text.length == 0)
    {
        self.addButton.enabled = YES;
        [searchBar performSelector: @selector(resignFirstResponder)
                    withObject: nil
                    afterDelay: 0.1];
    }
}

I'm creating an answer here for clarity, but the answer by Michaels helped massively and is the accepted approach here, although I got my code working. 为了清楚起见,我在这里创建一个答案,但是尽管我的代码可以正常工作,但是Michaels的答案在很大程度上为这提供了帮助,并且是这里公认的方法。

I did a lot of digging around with NSLogs and interestingly, I discovered that the shouldBeginEditing appeared before the textDidChange (in the order of the NSLogs). 我对NSLogs进行了很多研究,有趣的是,我发现shouldBeginEditing出现在textDidChange之前(按照textDidChange的顺序)。

However, I also noticed that in the steps in my original question, with the keyboard dismissed and the UISearchBar containing text and the x visible, if I tapped x, the keyboard didn't appear, but it called shoudlBeginEditing again. 但是,我还注意到,在原始问题的步骤中,关闭了键盘,并在UISearchBar中包含了文本,并且x可见,如果我轻按x,则不会出现键盘,但是它再次调用了shoudlBeginEditing

This was the method that was causing the addButton to continue to be greyed out because that method set that button to be disabled. 这是导致addButton继续变灰的方法,因为该方法将该按钮设置为禁用。

So I adjusted the code: 所以我调整了代码:

- (BOOL)searchBarShouldBeginEditing:(UISearchBar *)bar
{
    NSLog(@"Should begin");
    if ([self.timelineSearchBar.text length] > 0)
    {
        self.addButton.enabled = NO;
    }
    else
    {
        self.addButton.enabled = YES;
    }
    self.timelineSearchBar.showsCancelButton = NO;
    BOOL boolToReturn = self.shouldBeginEditing;
    self.shouldBeginEditing = YES;
    return boolToReturn;
}

I put the if condition in there so that the code reacted appropriately if I went back to the searchBar after cancelling with the x. 我将if条件放在其中,以便在用x取消后返回到searchBar时,代码可以适当地做出反应。

This way, the add button does not disable as soon as I click on the UISearchBar (which brings up the keyboard). 这样,添加按钮不会在我单击UISearchBar (弹出键盘)后立即禁用。 However, in the textDidChange (which is what I saw gets called from the very first letter being typed), I put the following condition too: 但是,在textDidChange (这是我看到的从键入的第一个字母开始调用的内容)中,我也设置了以下条件:

- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText
{
    NSLog(@"Text did change");
    self.timelineSearchBar.showsCancelButton = NO;
    if ([self.timelineSearchBar.text length] > 0)
    {
        self.addButton.enabled = NO;
    }
...
}

This way, the UISearchBar would only display the add button when I start typing in a letter. 这样, UISearchBar仅在我开始输入字母时才显示添加按钮。 This worked for me because if the user tapped on the UISearchBar and did not type anything in, in the prepareForSegue that went to the view that the Add Entry was calling, I checked if the searchBar isFirstResponder and if so, I resignFirstResponder . 这为我工作,因为如果用户轻敲上UISearchBar并没有在任何类型,在prepareForSegue那去认为,添加条目在呼唤,我检查,如果搜索栏isFirstResponder如果是这样,我resignFirstResponder

With this in mind, I'm not sure if this is the Apple way of doing things, but it's clean. 考虑到这一点,我不确定这是否是Apple的处理方式,但这很干净。 I'll know soon enough if my app gets rejected because of this, but thanks so much for your help Michaels; 我会尽快知道我的应用是否因此而因此而被拒绝,但是非常感谢Michaels的帮助; you really pointed me in the right direction for an issue that took up my entire afternoon! 您确实为解决整个我整个下午问题的正确方向指明了方向!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM