UISearchBar选择所有文本

7

有没有办法在UISearchBar中选择所有文本?我尝试使用[searchBar selectALL:],但它会抛出信号(未识别的选择器)。

我想允许用户更改以前的搜索文本。同时,当用户开始输入新请求时,旧请求应该被取消。实现它的标准方法是在文本开始编辑时选择所有文本。

7个回答

11

可以使用标准的UIResponder语义来实现。无需深入挖掘UISearchBar的私有视图层次结构。

[[UIApplication sharedApplication] sendAction:@selector(selectAll:) to:nil from:nil forEvent:nil]
你可以从任何地方调用它,selectAll:选择器将运行响应者链以查看是否有任何对象响应它。假设您的搜索栏当前是第一个响应者(如果用户正在其中输入),它将响应并结果将选择所有文本。如果没有,则可以通过在搜索栏上调用becomeFirstResponder使其成为第一个响应者。
[_mySearchBar becomeFirstResponder]
[[UIApplication sharedApplication] sendAction:@selector(selectAll:) to:nil from:nil forEvent:nil]

4

在我的情况下,在调用 becomeFirstResponder 后,发送 selectAll(_:) 不会立即生效。

我通过等待一个 runloop 来解决这个问题:

Swift 2:

dispatch_async(dispatch_get_main_queue()) {
    UIApplication.sharedApplication().sendAction(#selector(UITextField.selectAll(_:)), to: nil, from: nil, forEvent: nil)
}

Swift 3:

DispatchQueue.main.async(execute: {
    UIApplication.sharedApplication().sendAction(#selector(UITextField.selectAll(_:)), to: nil, from: nil, forEvent: nil)
})

4
如果你想要类似于在UITextField中选择文本所提供的“替换类型”功能(即交叉点上的额外轻敲是不可接受的),你可以查找UISearchBar的子视图以找到UITextField(或UISearchBarTextField)并选择其文本。
// need to select the searchBar text ... 
UITextField * searchText = nil;
for (UIView *subview in searchBar.subviews) 
{
    // we can't check if it is a UITextField because it is a UISearchBarTextField.
    // Instead we check if the view conforms to UITextInput protocol. This finds
    // the view we are after.
    if ([subview conformsToProtocol:@protocol(UITextInput)]) 
    {
        searchText = (UITextField*)subview;
        break;
    }
}

if (searchText != nil)
    [searchText selectAll:self];

2
请注意,在iOS 7中,这个方法已经不再适用了——文本字段现在嵌套在视图层次结构中更深的位置。为了解决这个问题,只需将代码更改为递归版本,遍历整个层次结构直到找到文本字段即可。根据您实际想要实现的功能,“selectAll:”方法也可能存在问题。请参见此问题以获取更多详细信息。还要注意,我必须在viewDidAppear中调用它才能使其正常工作,而不是在viewWillAppear中。 - Jan Holecek

2
这里有一个建议:当用户激活搜索栏时,有两种可能的意图:输入新的文字或添加到现有的文字中。我认为你应该给用户自由选择。
如果他想要添加文字,他自然会再次点击现有文字的末尾。
如果他想要重新开始,可以按清除按钮,该按钮在搜索栏激活时会自动出现。

好的,这是最佳解决方案。 - Mike Keskinov
7
在iOS上,Safari在您点击地址栏时会选择文本,这与其他浏览器的行为不同。 - Luke

1

Swift 4

如果你想要在searchBar成为第一响应者时选择所有文本。

func searchBarShouldBeginEditing(_ searchBar: UISearchBar) -> Bool {
    DispatchQueue.main.async {
        UIApplication.shared.sendAction(#selector(UITextField.selectAll(_:)), to: nil, from: nil, for: nil)
    }
    return true
}

0

我认为没有一种方法可以选择所有文本。也许当焦点在UISearchBar上时,您可以像这样清除搜索栏 - searchBar.text = @""

即清除搜索栏中的文本...希望这能在某种程度上帮助到您...


在这种情况下,用户无法更改请求。如果它是一个长字符串,重新输入可能会很烦人。 - Mike Keskinov

0
你可以通过保持一个 BOOL 变量来指示搜索栏文本字段是否处于编辑状态,并在 searchBar 代理方法中捕获第一个按键事件,从而实现此功能。
- (void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar {
   firstEdit = YES;
}

- (BOOL)searchBar:(UISearchBar *)searchBar 
       shouldChangeTextInRange:(NSRange)range 
       replacementText:(NSString *)text {

   if (firstEdit) {
      searchBar.text = text;
      firstEdit = NO;
   }
   return YES;
}

有没有办法突出显示文本? - Mike Keskinov

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接