Getting and Setting Cursor Position of UITextField and UITextView in Swift

匿名 (未验证) 提交于 2019-12-03 01:47:02

问题:

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.

回答1:

This answer has been updated for Swift 3

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



回答2:

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.



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