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


109

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

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

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

Answers:


316

以下内容适用于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()给予重点的文本字段,使键盘出现。

  • 请参阅此答案以获取如何在一定范围内获取文字。

也可以看看


startPosition的目的是什么?你能做什么呢?另外,可能需要获得光标位置的目的是什么?
蜂蜜

2
@Honey,我在这里使用该变量名来引用两个不同的东西。首先是指文本字段的开头。如果您想将光标移到那里,这将很有用。第二个是指请求选定范围的文本。如果要复制该范围或在其上设置一些属性,则很有用。
Suragch

文本框为空时,有什么可将光标向右移动的吗?我听了你的回答,但我做不到。
Yucel Bayram

1
@yucelbayram,您可以使用将光标放在H后面textField.endOfDocument。您也可以使用下划线或空格来表示缺少的字母。
Suragch

1
@ArielSD,对不起,我已经有一段时间没有为此工作了。我不记得了
Suragch

42

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

func textViewDidBeginEditing(_ textView: UITextView) {

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

从这个和其他线程没有其他工作。

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


2
这不是延迟,而是下一个运行循环。很有可能通过与相同的功能修改了文本字段的选定范围textViewDidBeginEditing。因此,通过将其放在队列中,它将在调用者完成后发生。
Michael Ozeryansky '18

@MichaelOzeryansky是的,我也是。但这引出了一个问题-手动设置光标位置的正确方法是什么?
timewonder

我也采用了这种解决方案
HattoriHanzō

1

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

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

对于重置光标位置:

textView.endFloatingCursor()

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


@Suragch浮动光标是一种在textView或textField中设置光标位置的方法。
Parth Patel

1
let range = field.selectedTextRange

field.text = "hello world"

field.selectedTextRange = range 
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.