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

前端 未结 7 1122
盖世英雄少女心
盖世英雄少女心 2020-11-28 13:43

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

相关标签:
7条回答
  • 2020-11-28 13:46

    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

    0 讨论(0)
  • 2020-11-28 13:55

    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];
    }
    
    0 讨论(0)
  • 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.

    0 讨论(0)
  • 2020-11-28 13:58

    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.

    0 讨论(0)
  • 2020-11-28 14:01

    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!)
    }
    
    
    0 讨论(0)
  • 2020-11-28 14:07

    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];
    
    0 讨论(0)
提交回复
热议问题