Can I select a specific block of text in a UITextField?

蓝咒 提交于 2019-11-26 08:29:38

问题


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 characters, or a specific range of characters, is that possible? if not, can I move the lines marking the beginning and end of the selection, as if the user is dragging them?


回答1:


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 ;)


Update for iOS5 and above :

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



回答2:


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 UITextFields 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 NSRanges. https://gist.github.com/4463233




回答3:


To select the name of a file without the file extension, use this:

-(void) tableViewCellDidBeginEditing:(UITableViewTextFieldCell*) cell
{
    NSInteger fileNameLengthWithoutExt = [self.filename length] - [[self.filename pathExtension] length];
    UITextField* textField = cell.textField;
    UITextPosition* start = [textField beginningOfDocument];
    UITextPosition* end = [textField positionFromPosition:start offset: fileNameLengthWithoutExt - 1]; // the -1 is for the dot separting file name and extension
    UITextRange* range = [textField textRangeFromPosition:start toPosition:end];
    [textField setSelectedTextRange:range];
}



回答4:


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.




回答5:


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



回答6:


Swift

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.




回答7:


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!)
}



来源:https://stackoverflow.com/questions/3277538/can-i-select-a-specific-block-of-text-in-a-uitextfield

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!