Suragch Suragch - 5 months ago 128
iOS Question

Getting and Setting Cursor Position of UITextField and UITextView in Swift

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



But since I am working with Swift, I wanted to learn how to get the current cursor location and also set it in Swift.

The answer below is the the result of my experimentation and translation from Objective-C.

Answer

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.offsetFromPosition(textField.beginningOfDocument, toPosition: 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.textRangeFromPosition(newPosition, toPosition: newPosition)

To the end

let newPosition = textField.endOfDocument
textField.selectedTextRange = textField.textRangeFromPosition(newPosition, toPosition: 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.positionFromPosition(selectedRange.start, inDirection: UITextLayoutDirection.Left, offset: 1) {

        // set the new position
        textField.selectedTextRange = textField.textRangeFromPosition(newPosition, toPosition: newPosition)
    }
}

To an arbitrary position

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

let arbitraryValue: Int = 5
if let newPosition = textField.positionFromPosition(textField.beginningOfDocument, inDirection: UITextLayoutDirection.Right, offset: arbitraryValue) {

    textField.selectedTextRange = textField.textRangeFromPosition(newPosition, toPosition: newPosition)
}

Related

Select all text

textField.selectedTextRange = textField.textRangeFromPosition(textField.beginningOfDocument, toPosition: textField.endOfDocument)

Select a range of text

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

Insert text at the current cursor position

textField.insertText("Hello")

Notes

  • This answer uses a text field, but the same concepts apply to UITextView.

  • 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.

Related