I have a UITextField in my iPhone app. I know how to make the text field select all of its text, but how can change the selection? Say I wanted to select the last 5 characte
To select a specific range of characters you can do something like this in iOS 5+
int start = 2;
int end = 5;
UITextPosition *startPosition = [self positionFromPosition:self.beginningOfDocument offset:start];
UITextPosition *endPosition = [self positionFromPosition:self.beginningOfDocument offset:end];
UITextRange *selection = [self textRangeFromPosition:startPosition toPosition:endPosition];
self.selectedTextRange = selection;
Since UITextField
s and other UIKit elements have their own private subclasses of UITextPosition
and UITextRange
you can not create new values directly, but you can use the text field to create them for you from a reference to the beginning or end of the text and an integer offset.
You can also do the reverse to get integer representations of the start and end points of the current selection:
int start = [self offsetFromPosition:self.beginningOfDocument toPosition:self.selectedTextRange.start];
int end = [self offsetFromPosition:self.beginningOfDocument toPosition:self.selectedTextRange.end];
Here is a category which adds methods to handle selections using NSRange
s. https://gist.github.com/4463233
Just a small addition to the accepted answer. In iOS 5, the following line crashes my app when UITextView's text length is 0 (has no text):
[self textRangeFromPosition:startPosition toPosition:endPosition];
A small workaround is to add a length == 0
check like:
if (textField.text && textField.text.length > 0) {
// Get current selected range , this example assumes is an insertion point or empty selection
UITextRange *selectedRange = [textField selectedTextRange];
// Calculate the new position, - for left and + for right
UITextPosition *newPosition = [textField positionFromPosition:selectedRange.start offset:-5];
// Construct a new range using the object that adopts the UITextInput, our textfield
UITextRange *newRange = [textField textRangeFromPosition:newPosition toPosition:selectedRange.start];
// Set new range
[textField setSelectedTextRange:newRange];
}
Select the last 5 characters:
if let newPosition = textField.positionFromPosition(textField.endOfDocument, inDirection: UITextLayoutDirection.Left, offset: 5) {
textField.selectedTextRange = textField.textRangeFromPosition(newPosition, toPosition: textField.endOfDocument)
}
Select an arbitrary range:
// Range: 3 to 7
let startPosition = textField.positionFromPosition(textField.beginningOfDocument, inDirection: UITextLayoutDirection.Right, offset: 3)
let endPosition = textField.positionFromPosition(textField.beginningOfDocument, inDirection: UITextLayoutDirection.Right, offset: 7)
if startPosition != nil && endPosition != nil {
textField.selectedTextRange = textField.textRangeFromPosition(startPosition!, toPosition: endPosition!)
}
My full answer is here.
These both work for me:
[UITextField selectAll:self];
and:
UITextField.selectedRange = NSMakeRange(0, 5);
but only if the text field is the first responder. (In other words, only if the keyboard is showing.) So, you need to precede either of the select methods with this:
[UITextField becomeFirstResponder];
if you want the text to appear selected.
Swift 5.0
here is how I selecte file name Panda
from Panda.txt
func textFieldDidBeginEditing(_ textField: UITextField) {
// if textField.text is `Panda.txt`, offset will be 3
let offset = String(textField.text!.split(separator: ".").last!).length
let from = textField.position(from: textField.beginningOfDocument, offset: 0)
let to = textField.position(from: textField.beginningOfDocument,
offset:textField.text!.length - (offset+1) )
//now `Panda` will be selected
textField.selectedTextRange = textField.textRange(from: from!, to: to!)
}
With UITextField, you cannot. But if you see the headers, you have _selectedRange and others that might be used if you add some categories to it ;)
Now UITextField and UITextView conform to UITextInput protocol so it is possible :)
Selecting the last 5 characters before the caret would be like this:
// Get current selected range , this example assumes is an insertion point or empty selection
UITextRange *selectedRange = [textField selectedTextRange];
// Calculate the new position, - for left and + for right
UITextPosition *newPosition = [textField positionFromPosition:selectedRange.start offset:-5];
// Construct a new range using the object that adopts the UITextInput, our textfield
UITextRange *newRange = [textField textRangeFromPosition:newPosition toPosition:selectedRange.start];
// Set new range
[textField setSelectedTextRange:newRange];