Programmatically Select all text in UITextField
Asked Answered
C

12

83

How can I programmatically select all text in UITextField?

Comeau answered 6/11, 2009 at 19:45 Comment(0)
E
66

Turns out, calling -selectAll: with a non-nil sender displays the menu. Calling it with nil causes it to select the text, but not display the menu.

I tried this after my bug report about it came back from Apple with the suggestion that I pass nil instead of self.

No need to muck with UIMenuController or other selection APIs.

Emperor answered 12/2, 2014 at 0:32 Comment(4)
I've been trying to figure out how to select the text without displaying the menu. Thanks adding that tid-bit.Augustusaugy
Doesn't seem to work for the text field of an alert controller.Unpredictable
Forget it, for alert controllers this answer works: https://mcmap.net/q/153523/-select-text-in-uialertcontroller-39-s-text-fieldUnpredictable
+1 for proper answer. Another +1 for mentioning about sender and menu. Another +1 for mentioning source of information. Sadly, I have only one vote...Geniagenial
A
88

Thats what did the trick for me:

[self.titleField setSelectedTextRange:[self.titleField textRangeFromPosition:self.titleField.beginningOfDocument toPosition:self.titleField.endOfDocument]];

Pretty ugly but it works, so there will be no sharedMenuController shown!

To fix the "only works every second time" problem use following:

__weak typeof(self) weakSelf = self;
dispatch_async(dispatch_get_main_queue(), ^{
    __strong __typeof(weakSelf) strongSelf = weakSelf;
    UITextRange *range = [strongSelf textRangeFromPosition:strongSelf.beginningOfDocument toPosition:strongSelf.endOfDocument];
    [strongSelf setSelectedTextRange:range];
});

Thanks to Eric Baker ( just edited from comment in here )

Alphosis answered 28/5, 2013 at 22:39 Comment(10)
This is actually a far superior answer to the question. It does what is asked for without any silly workarounds to prevent the menu being shown (which don't work for me anyway).Diverting
Sorry to bring this back, but your solution works only the first time. The second time, it failed. Basically, what I did was that when users click on UITextField, select all text so they can override all of it, they can dismiss the keyboard by clicking something else (a background transparent in this case), after that clicking the same UITextField does not do the trick anymore. Repeat this process, I notice that it works for the odd time but does not work for the even time. I.e: works for first, third, fifth ; does not work for second, fourth, sixth.Keelin
@LeonNguyen This works for me to solve the problem you describe: __weak typeof(self) weakSelf = self; dispatch_async(dispatch_get_main_queue(), ^{ __strong __typeof(weakSelf) strongSelf = weakSelf; UITextRange *range = [strongSelf textRangeFromPosition:strongSelf.beginningOfDocument toPosition:strongSelf.endOfDocument]; [strongSelf setSelectedTextRange:range]; });Klockau
@EricBaker I can confirm that your solution worked. It seems to be an issue with threading. ThanksKeelin
This IS the answer.Ghyll
If this doesn't work for you, try calling [self.titleField becomeFirstResponder]; first so that your text field will get cursor focus and the keyboard will appear.Ramsey
is it possible to hide the blue lines (the ones for adjusting the selection)?Akira
The __weak / __strong hack didn't work for me. I had to deselect all text upon endEditing so it could be freshly selected upon startEditing.Barcot
@LeonNguyen please provide your code __weak typeof(self) weakSelf = self; dispatch_async(dispatch_get_main_queue(), ^{ __strong __typeof(weakSelf) strongSelf = weakSelf; UITextRange *range = [strongSelf textRangeFromPosition:strongSelf.beginningOfDocument toPosition:strongSelf.endOfDocument]; [strongSelf setSelectedTextRange:range]; }); in swiftStint
The DispatchQueue.main.async here was the key for me, without it, menu always showed upOptician
E
66

Turns out, calling -selectAll: with a non-nil sender displays the menu. Calling it with nil causes it to select the text, but not display the menu.

I tried this after my bug report about it came back from Apple with the suggestion that I pass nil instead of self.

No need to muck with UIMenuController or other selection APIs.

Emperor answered 12/2, 2014 at 0:32 Comment(4)
I've been trying to figure out how to select the text without displaying the menu. Thanks adding that tid-bit.Augustusaugy
Doesn't seem to work for the text field of an alert controller.Unpredictable
Forget it, for alert controllers this answer works: https://mcmap.net/q/153523/-select-text-in-uialertcontroller-39-s-text-fieldUnpredictable
+1 for proper answer. Another +1 for mentioning about sender and menu. Another +1 for mentioning source of information. Sadly, I have only one vote...Geniagenial
P
54

Use what you need

ObjC

[yourtextField becomeFirstResponder]; //puts cursor on text field
[yourtextField selectAll:nil];  //highlights text
[yourtextField selectAll:self]; //highlights text and shows menu(cut copy paste)

Swift

yourTextField.becomeFirstResponder() //puts cursor on text field
yourTextField.selectAll(nil)  //highlights text
yourTextField.selectAll(self) //highlights text and shows menu(cut copy paste)
Paperweight answered 1/8, 2014 at 1:53 Comment(3)
Best answer here. Super simple, and the 'nil' trick to hide the Cut/Copy/Pate pop-up does the trick!Underpin
This is the best/simplest answerNickelson
Note if you want to select text when first showing a view, you must place the selectAll call in viewDidAppear. It will not work when placed in viewDidLoad or viewWillAppear.Drus
Z
50

I just tested this to verify Mirko's comment above, but my test verifies that selectAll: does in fact select all the text when it's sent to the UITextField itself.

Note that the text will be immediately obscured with CUT | COPY | PASTE actions, but to your question, it is exactly what appears when a user taps "Select All" to begin with.

The solution I'm going with follows, note that the second line will temporarily hide the CUT/COPY/PASTE dialog, without disabling it for explicit user selections

[_myTextField selectAll:self];
[UIMenuController sharedMenuController].menuVisible = NO;
Zelaya answered 31/1, 2010 at 18:43 Comment(3)
I want to select all text when the user taps the UITextField, so that as soon as they start typing, original text gets erased. Which Outlet action should I call to achieve this? I tried linking touch up inside to an IBAction which calls your code above but didn't work.Sunken
Just to let you know that it didn't work for me :( The menu is still not visible when we call [UIMenuController sharedMenuController].menuVisible = NO; so that line won't have any effect.Aguilera
Actually to select all the text so that the menu doesn't appear you have to use setSelectedRange: instead.Aguilera
B
13

This is the best solution I've found. No sharedMenuController, and it works consecutively:

-(void)textFieldDidBeginEditing:(UITextField *)textField
{
    [textField performSelector:@selector(selectAll:) withObject:nil afterDelay:0.1];
}
Bumpkin answered 9/12, 2016 at 21:19 Comment(4)
When adding an answer years after a question has been asked, would be good to explain why you are adding yet another answer. There are many existing answers here: under what conditions is your answer "better" than all of those? What is the benefit? Are there situations where it might not be beneficial, and what existing answer would you use then?Psf
Thank you! This approach, or rather the Swift equivalent "textField.perform(#selector(selectAll), with: nil, afterDelay: 0.01)", fixes the issue Leon Nguyen was having with blackforestcowboy's answer above, where it only works every other time. Something about delaying the action must sort out the threading. As @Psf says, it would be useful to explain that in the answer here.Parole
Not sure if prettier, but without selector(s) I've been able to get the menu to NOT show up by calling: DispatchQueue.main.asyncAfter(deadline: .now() + 0.1, execute: { textField.selectAll(nil) })Drayton
Used the suggestion from @Drayton with SwiftUI-Introspect in my SwiftUI project. Worked great.Predate
W
9

Swift

Select all text in a UITextField:

textField.selectedTextRange = textField.textRange(from: textField.beginningOfDocument, to: textField.endOfDocument)

My full answer is here: https://mcmap.net/q/149124/-getting-and-setting-cursor-position-of-uitextfield-and-uitextview-in-swift

Wiese answered 21/1, 2016 at 11:40 Comment(2)
BTW, if there is a Swift equivalent to the shorter alternative solution [textField selectAll:nil], would be good to list that also.Psf
Yes, if anyone knows it, please leave a comment.Wiese
M
3

To be able to select text, the text field has to be editable. To know when the text field is editable use the delegate methods:

- (void)textFieldDidBeginEditing:(UITextField *)textField
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField

I don't think textFieldShouldBeginEditing: is required but it's what I used in my implementation.

- (void)textFieldDidBeginEditing:(UITextField *)textField{
    [textField selectAll:textField];
}

- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField{
    return YES;
}

Passing in nil to selectAll: won't show the Menu.

Mencher answered 5/2, 2015 at 16:54 Comment(0)
E
2

Unfortunately I don't think you can do that.

I'm not sure if this helps you, but setClearsOnBeginEditing lets you specify that the UITextField should delete the existing value when the user starts editing (this is the default for secure UITextFields).

Elurd answered 9/11, 2009 at 20:58 Comment(0)
E
2

Swift 3:

textField.selectAll(self)
Eaddy answered 1/9, 2017 at 15:22 Comment(0)
A
1

I create a custom alert view which contains a UITextField inside. I found a problem to the textfield is that: beginningOfDocument only has value if textfield is added to screen & becomeFirstResponder is called.

Otherwise beginningOfDocument returns nil and [UITextField textRangeFromPosition:] can not get the value.

So here is my sample code to solve this case.

UIWindow *window = [[[UIApplication sharedApplication] windows] firstObject];
[window addSubview:theAlertView]; // textfield must be added as a subview of screen first
UITextField *textField = theAlertView.textField;
[textField becomeFirstResponder]; // then call to show keyboard and cursor 
UITextRange *range = [textField textRangeFromPosition:textField.beginningOfDocument toPosition:textField.endOfDocument]; // at this time, we could get beginningOfDocument
[textField setSelectedTextRange:range]; // Finally, it works!!!
Ascertain answered 5/2, 2015 at 11:36 Comment(0)
P
0
UITextField *tf = yourTF;
// hide cursor (you have store default color!!!)
[[tf valueForKey:@"textInputTraits"] setValue:[UIColor clearColor]
                                       forKey:@"insertionPointColor"];
// enable selection
[tf selectAll:self];
// insert your string here
// and select nothing (!!!)
[tf setMarkedText:@"Egor"
    selectedRange:NSMakeRange(0, 0)];

Done!

Papaveraceous answered 29/11, 2013 at 20:33 Comment(0)
M
-2

If you mean how would you allow the user to edit the text in a uitextfield then just assign firstResponder to it:

[textField becomeFirstResponder]

If you mean how do you get the text in the uitextfield than this will do it:

textField.text

If you mean actually select the text (as in highlight it) then this will may be useful:

selectAll

Motorize answered 6/11, 2009 at 19:50 Comment(3)
Actually I want to select all the text programatically (highlight), the same as when user taps once on text and then taps on "Select All"Comeau
The last method is what you want then.Mab
Actually not: This method is invoked when the user taps the Select All command of the editing menu. What I want is to invoke Select All, like if the user tapped Select All command.Comeau

© 2022 - 2024 — McMap. All rights reserved.