Getting and Setting Cursor Position of UITextField and UITextView in Swift

后端 未结 4 965
遥遥无期
遥遥无期 2020-11-22 17:10

I\'ve been experimenting with UITextField and how to work with it\'s cursor position. I\'ve found a number of relation Objective-C answers, as in

相关标签:
4条回答
  • 2020-11-22 17:31
    let range = field.selectedTextRange
    
    field.text = "hello world"
    
    field.selectedTextRange = range 
    
    0 讨论(0)
  • 2020-11-22 17:33

    in my case I had to use DispatchQueue:

    func textViewDidBeginEditing(_ textView: UITextView) {
    
       DispatchQueue.main.async{
          textField.selectedTextRange = ...
       }
    }
    

    nothing else from this and other threads worked.

    PS: I double checked which thread did textViewDidBeginEditing was running on, and it was main thread, as all UI should run on, so not sure why that little delay using main.asynch worked.

    0 讨论(0)
  • 2020-11-22 17:38

    The following content applies to both UITextField and UITextView.

    Useful information

    The very beginning of the text field text:

    let startPosition: UITextPosition = textField.beginningOfDocument
    

    The very end of the text field text:

    let endPosition: UITextPosition = textField.endOfDocument
    

    The currently selected range:

    let selectedRange: UITextRange? = textField.selectedTextRange
    

    Get cursor position

    if let selectedRange = textField.selectedTextRange {
    
        let cursorPosition = textField.offset(from: textField.beginningOfDocument, to: selectedRange.start)
    
        print("\(cursorPosition)")
    }
    

    Set cursor position

    In order to set the position, all of these methods are actually setting a range with the same start and end values.

    To the beginning

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

    To the end

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

    To one position to the left of the current cursor position

    // only if there is a currently selected range
    if let selectedRange = textField.selectedTextRange {
    
        // and only if the new position is valid
        if let newPosition = textField.position(from: selectedRange.start, offset: -1) {
    
            // set the new position
            textField.selectedTextRange = textField.textRange(from: newPosition, to: newPosition)
        }
    }
    

    To an arbitrary position

    Start at the beginning and move 5 characters to the right.

    let arbitraryValue: Int = 5
    if let newPosition = textField.position(from: textField.beginningOfDocument, offset: arbitraryValue) {
    
        textField.selectedTextRange = textField.textRange(from: newPosition, to: newPosition)
    }
    

    Related

    Select all text

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

    Select a range of text

    // Range: 3 to 7
    let startPosition = textField.position(from: textField.beginningOfDocument, offset: 3)
    let endPosition = textField.position(from: textField.beginningOfDocument, offset: 7)
    
    if startPosition != nil && endPosition != nil {
        textField.selectedTextRange = textField.textRange(from: startPosition!, to: endPosition!)
    }
    

    Insert text at the current cursor position

    textField.insertText("Hello")
    

    Notes

    • Use textField.becomeFirstResponder() to give focus to the text field and make the keyboard appear.

    • See this answer for how to get the text at some range.

    See also

    • How to Create a Range in Swift
    0 讨论(0)
  • 2020-11-22 17:42

    For set cursor position at your point:

    textView.beginFloatingCursor(at: CGPoint(x: 10.0, y: 10.0))
    

    For reset cursor position:

    textView.endFloatingCursor()
    

    Note: This example works in both Textview & Textfield.

    0 讨论(0)
提交回复
热议问题