【问题标题】:Perform action on UISearchBar when Keyboard is down and the x has been tapped当键盘按下并点击 x 时对 UISearchBar 执行操作
【发布时间】:2014-05-21 03:19:44
【问题描述】:

我有一个UITableView,顶部有一个UISearchBar,并且有一个不起作用的特定要求。

我的UISearchBar (showsCancelButton = NO) 上没有取消按钮,所以我完全依靠UISearchBar 中的x 来取消现有的搜索。我依靠键盘的“搜索”按钮来关闭键盘(尽管在我的情况下它被称为完成)。

当用户在我的应用中搜索时,我将禁用 navigation bar button 项目,因为它会带来糟糕的用户体验,并且只有在搜索取消后,用户才会返回导航栏按钮项目。这一切都在工作。

我有一个特殊的场景,但我无法解决。

1) 点击搜索栏输入文字

2) 单击键盘上的完成,键盘将消失

3) 键盘退出后,x 仍保留在UISearchBar

4) 点击UISearchBar中的x,SearchBar中的文字消失,视图刷新

5) 此时,导航栏按钮应该再次启用,但它不是。

代码:

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

我知道上面的代码是为了在按下 x 时关闭键盘,这很好。

在我的情况下,键盘已经退出,所以我希望点击 x 来重新启用导航栏项目。

    self.addButton.enabled = YES; 

因为上面的 if 语句根本没有做任何事情,并且导航栏项目仍然被禁用。

我什至在那个 if 语句中尝试过:

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

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

但是说 searchBar 不响应该 enableAdd 选择器会崩溃。

我已经做了一个断点,当我点击 x 并进入语句时,上面的 if 语句确实评估为 true,它“运行”代码以启用按钮,但它从未发生过。

另外我的最终编辑方法是:

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

更新:我尝试了http://engineeringtheworld.wordpress.com/2011/04/11/detecting-when-clear-is-clicked-in-uisearchbar-x-button/ 此处的链接,但没有成功 - 没有调用 textField 的 shouldClear 方法。我正在使用 iOS 7,所以也许还有另一种方法可以使用 textFields 嵌入视图?这很可能是正确的方法,但它不适用于我的代码,因为该示例中的 for 语句永远不会被评估为 true(我放入了 NSLog)。

更新 2:从上面的 if 语句中,我调用了 searchBarCancelButton 方法并导致了极端循环,所以这当然不是正确的方法:

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

对此的任何指导将不胜感激。我知道我错过了一个关键步骤,但我就是想不通。

【问题讨论】:

  • 你在哪里设置addButton.enabled = NO
  • 嗨,Michael,在 searchBarShouldBeginEditing 和 searchBarSearchButtonClicked 中使用 if ([self.timelineSearchBar.text length] > 0) 语句,否则在此委托方法中再次启用按钮。没有其他地方设置为 NO

标签: ios selector uisearchbar uisearchbardelegate


【解决方案1】:

问题是当点击 X 按钮时,searchBar:textDidChange: 被调用之前 searchBarShouldBeginEditing:

即这是调用流程:searchBar:textDidChange: -> searchBarShouldBeginEditing: -> searchBarTextDidBeginEditing: -> searchBarTextDidEndEditing:

textDidChange 将启用设置为“是”,但随后shouldBeginEditing 再次禁用它。这对我来说非常有效:

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

【讨论】:

  • 非常感谢@michaels - 我非常感谢您的想法和工作。为了清楚起见,我已经回答了这个问题,但如果没有您的输入,我永远不会到达那里,而且我几乎让您的代码正常工作;只需要稍微调整一下。再次感谢您的帮助,并且非常有兴趣通过我必须使用的方法来获得您的想法
【解决方案2】:
-(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];
    }
}

【讨论】:

  • 感谢@Goutham - 这很有帮助,但不幸的是结果相同。我所看到的是,在键盘向上(isFirstResponder)的情况下,如果我点击取消按钮,那么键盘会退出并且导航栏按钮(addButton)会启用。但是,由于键盘已经 resignFirstResponder,UISearchBar 中的 x 不会启用导航栏按钮项。我想知道这是否是 iOS 中的错误。
【解决方案3】:

为了清楚起见,我在这里创建了一个答案,但 Michaels 的答案帮助很大,并且是这里公认的方法,尽管我的代码可以正常工作。

我对@9​​87654321@ 做了很多研究,有趣的是,我发现shouldBeginEditing 出现在textDidChange 之前(按照NSLogs 的顺序)。

但是,我还注意到,在我最初问题的步骤中,键盘被关闭并且 UISearchBar 包含文本和 x 可见,如果我点击 x,键盘没有出现,但它再次调用 shoudlBeginEditing .

这是导致 addButton 继续灰显的方法,因为该方法将该按钮设置为禁用。

于是我调整了代码:

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

我把 if 条件放在那里,这样如果我在用 x 取消后返回 searchBar,代码就会做出适当的反应。

这样,当我点击UISearchBar(打开键盘)时,添加按钮不会被禁用。然而,在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;
    }
...
}

这样,UISearchBar 只会在我开始输入字母时显示添加按钮。这对我有用,因为如果用户点击 UISearchBar 并且没有输入任何内容,则在 prepareForSegue 中转到 Add Entry 正在调用的视图中,我检查了 searchBar isFirstResponder 是否是这样,我resignFirstResponder

考虑到这一点,我不确定这是否是 Apple 的做事方式,但它很干净。如果我的应用程序因此而被拒绝,我很快就会知道,但非常感谢您的帮助 Michaels;你真的为我整个下午的问题指明了正确的方向!

【讨论】:

  • 很高兴看到您成功了!我非常怀疑您会因此而被拒绝您的应用程序,因为您没有使用任何私有 API 或做任何危险的事情(在我看来)。我很惊讶您看到 shouldBeginEditingtextDidChange 之前被调用 - 我的结果相反,但是嘿,如果它有效,它就有效!
  • 绝对!令人困惑,但它有效,我很高兴 :) 再次感谢 Michaels - 非常感谢!
猜你喜欢
  • 2011-05-10
  • 1970-01-01
  • 2013-07-11
  • 1970-01-01
  • 2014-11-24
  • 1970-01-01
  • 2011-01-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多