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

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

但是因为我正在与 Swift 一起工作,所以我想学习如何获得当前的光标位置并在 Swift 中设置它。

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

127487 次浏览

以下内容适用于 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)
}

相关

选择所有文本

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

选择一个文本范围

// 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 运行在哪个线程上,它是主线程,因为所有 UI 都应该在上面运行,所以不确定为什么使用 main.synch 的那个小延迟可以工作。

用于设置光标在您所在位置的位置:

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
}
}

插入符号仍然在左边,这是不理想的,但至少与’如果’语句添加,它只会添加文本从中心的意图,不会添加文本从左边。