Select all text in UISearchBar on beginEditing?

2019-07-16 10:49发布

I’m trying to emulate the behaviour of the address bar in iOS Safari – that is, if there’s text in the address bar when it’s tapped, it is selected. Much in the same way most desktop browsers work, too. I don’t want to CLEAR it on selection, merely select what’s inside, so that if the user then begins typing, it’ll clear, but the user also has the ability to edit the existing string if they want to.

I’ve tried the following, it finds the UISearchBarTextField inside the subviews under both iOS7 and iOS6, but calling selectAll on it doesn’t seem to have any effect. I’ve tried changing its text property, that works fine, it’s just selectAll that isn’t happy.

I’ve also tried changing the argument to selectAll: to self and a couple other things, no change, just doesn’t wanna select the text in there!

Any thoughts? Here’s my code:

- (void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar
{
    NSArray *subviews = [UIDevice isRunningiOS7OrAbove]
    ? [[searchBar.subviews objectAtIndex:0] subviews]
    : searchBar.subviews;

    for (UIView *subview in subviews) {
        if ([subview conformsToProtocol:@protocol(UITextInputTraits)]) {
            UITextField *textField = (UITextField *)subview;
            [textField selectAll:textField];
        }
    }
}

EDIT

I’ve also tried this, with no joy:

for (UIView *subview in subviews) {
    if ([subview conformsToProtocol:@protocol(UITextInputTraits)]) {
        UITextField *textField = (UITextField *)subview;
        [textField setSelectedTextRange:[textField textRangeFromPosition:[textField beginningOfDocument]
                                                              toPosition:[textField endOfDocument]]];
    }
}

3条回答
女痞
2楼-- · 2019-07-16 10:57

Ran into the same problem. The thing that helped me was delaying the selectAll by a short period of time.

I made this extension for UISearchBar

extension UISearchBar {
    func selectAllText() {
        guard let searchTF = self.valueForKey("searchField") as? UITextField else {
            return
        }

        if searchTF.respondsToSelector(#selector(NSObject.selectAll(_:))) {
            searchTF.selectAll(nil)
        }
    }
}

then I simply call this method on my searchbar with a short delay.

Swift 2

let dispatchTime: dispatch_time_t = dispatch_time(DISPATCH_TIME_NOW, Int64(0.05 * Double(NSEC_PER_SEC))) 
dispatch_after(dispatchTime, dispatch_get_main_queue(), { [weak self] in
    self?.nameSearchBar.selectAllText()
})

Swift 3 Xcode 8 beta 4

DispatchQueue.main.asyncAfter(deadline: .now() + 0.05) { [weak self] in
    self?.nameSearchBar.selectAllText()
}

WARNING: This approach is far from clear solution, but it works fine. The short delay shouldn't cause any trouble since it's just a selecting action on a textfield. Though accessing the searchField property of your UISearchBar can lead to app rejection!

查看更多
等我变得足够好
3楼-- · 2019-07-16 11:14

You can use: [UITextField setSelectedTextRange:(UITextRange *)]

- (void)textFieldDidBeginEditing:(UITextField*)textField {

 UITextPosition *start = [textField beginningOfDocument];

 UITextPosition *end   = [textField endOfDocument];

 UITextRange *range = [textField textRangeFromPosition:start toPosition:end];

 [textField setSelectedTextRange:range];

 }

Now you can implement using UISearchBar...

查看更多
女痞
4楼-- · 2019-07-16 11:14

For me passing UITextField parameter didnt work. I am passing to selectAll method nil param so your line should look like:

    [textField selectAll:nil];
查看更多
登录 后发表回答