关于ios:在Swift中获取和设置UITextField和UITextView的光标位置

Getting and Setting Cursor Position of UITextField and UITextView in Swift

我一直在尝试UITextField以及如何使用它的光标位置。 我发现了许多与Objective-C相关的答案,例如

  • 在iOS中获取UITextField的光标位置
  • 控制UITextField中的光标位置
  • UITextField获取当前编辑的单词

但是由于我正在使用Swift,所以我想学习如何获取当前光标位置以及如何在Swift中进行设置。

下面的答案是我从Objective-C进行实验和翻译的结果。


以下内容适用于UITextFieldUITextView

有用的信息

文本字段文本的最开始:

1
let startPosition: UITextPosition = textField.beginningOfDocument

文本字段文本的末尾:

1
let endPosition: UITextPosition = textField.endOfDocument

当前选择的范围:

1
let selectedRange: UITextRange? = textField.selectedTextRange

获取光标位置

1
2
3
4
5
6
if let selectedRange = textField.selectedTextRange {

    let cursorPosition = textField.offset(from: textField.beginningOfDocument, to: selectedRange.start)

    print("\(cursorPosition)")
}

设定光标位置

为了设置位置,所有这些方法实际上都是使用相同的开始值和结束值来设置范围。

从头开始

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

到最后

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

在当前光标位置左侧的一个位置

1
2
3
4
5
6
7
8
9
10
// 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)
    }
}

到任意位置

从头开始,向右移动5个字符。

1
2
3
4
5
let arbitraryValue: Int = 5
if let newPosition = textField.position(from: textField.beginningOfDocument, offset: arbitraryValue) {

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

有关

选择所有文字

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

选择文本范围

1
2
3
4
5
6
7
// 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!)
}

在当前光标位置插入文本

1
textField.insertText("Hello")

笔记

  • 使用textField.becomeFirstResponder()将焦点放在文本字段上,并使键盘出现。

  • 有关如何在一定范围内获取文字的信息,请参见此答案。

也可以看看

  • 如何在Swift中创建范围


就我而言,我必须使用DispatchQueue:

1
2
3
4
5
6
func textViewDidBeginEditing(_ textView: UITextView) {

   DispatchQueue.main.async{
      textField.selectedTextRange = ...
   }
}

此线程和其他线程没有其他作用。

PS:我仔细检查了textViewDidBeginEditing在哪个线程上运行,并且该线程是主线程,因为所有UI都应在此线程上运行,所以不确定为什么使用main.asynch的延迟如此短。


1
2
3
4
5
let range = field.selectedTextRange

field.text ="hello world"

field.selectedTextRange = range

对于您要设置的光标位置:

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

对于重置光标位置:

1
textView.endFloatingCursor()

注意:此示例在Textview和Textfield中均适用。