在 Swift 中获取和设置 UITextField 和 UITextView 的光标位置

Getting and Setting Cursor Position of UITextField and UITextView in Swift

我一直在试验 UITextField 以及如何使用它的光标位置。我找到了一些关系 Objective-C 的答案,如

但由于我正在使用 Swift,我想了解如何获取当前光标位置并将其设置在 Swift。

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

以下内容适用于UITextFieldUITextView

有用信息

文本字段文本的开头:

let startPosition: UITextPosition = textField.beginningOfDocument

文本字段文本的最末尾:

let endPosition: UITextPosition = textField.endOfDocument

当前选择的范围:

let selectedRange: UITextRange? = textField.selectedTextRange

获取光标位置

if let selectedRange = textField.selectedTextRange {

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

    print("\(cursorPosition)")
}

设置光标位置

为了设置位置,这些方法其实都是设置一个范围,起始值和结束值都一样

到头

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

到最后

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

到当前光标位置左边一位

// 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 个字符。

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

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

相关

Select所有文字

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

Select 文本范围

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

在当前光标位置插入文本

textField.insertText("Hello")

备注

  • 使用 textField.becomeFirstResponder() 将焦点置于文本字段并显示键盘。

  • 请参阅 了解如何在某个范围内获取文本。

另见

在我的例子中,我不得不使用 DispatchQueue:

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

此线程和其他线程均无任何效果。

PS:我仔细检查了哪个线程执行了 textViewDidBeginEditing 运行ning,它是主线程,因为所有 UI 都应该 运行,所以不是确定为什么使用 main.asynch 的小延迟有效。

要在您的位置设置光标位置:

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

重置光标位置:

textView.endFloatingCursor()

注意:此示例在 Textview 和 Textfield 中都有效。

let range = field.selectedTextRange

field.text = "hello world"

field.selectedTextRange = range 

我什至没有注意到我发布的一个应用程序中的 textView 在您删除 textView 顶行的一个词后实际上是从左边开始的。 插入符号不仅向左移动,而且文本将从您键入内容时插入符号所在的左侧开始! 它不会在中线或底线执行,只有在顶部删除线时才会执行。

func textViewDidChange(_ textView: UITextView)
{
   if myTextView.text!.count > 0
   {
      myTextView.textAlignment = .center
   }
}

插入符号仍然向左移动,这并不理想,但至少添加了 'if' 语句后,它只会按预期从中心添加文本,而不会从左侧添加文本.