【问题标题】:Getting and Setting Cursor Position of UITextField and UITextView in Swift在 Swift 中获取和设置 UITextField 和 UITextView 的光标位置
【发布时间】:2016-04-27 14:44:56
【问题描述】:

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

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

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

【问题讨论】:

    标签: ios swift uitextfield uitextview uitextposition


    【解决方案1】:

    以下内容同时适用于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() 将焦点放在文本字段上并显示键盘。

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

    另见

    【讨论】:

    • startPosition 的目的是什么?你能用它做什么?另外,获取光标位置的目的是什么?
    • @Honey,我在这里使用该变量名来指代两个不同的事物。第一个是引用文本字段的开头。如果您想将光标移动到那里,这将很有用。第二个是指对选定范围的文本的乞求。如果您想复制该范围或在其上设置一些属性,这很有用。
    • 文本字段为空时,有什么可以将光标向右移动吗?我听从了你的回答,但我做不到。
    • @yucelbayram,您可以使用textField.endOfDocument将光标放在H之后。您也可以使用下划线或空格来表示缺失的字母。
    • @ArielSD,很抱歉,我有一段时间没有处理这个问题了。我不记得了。
    【解决方案2】:

    就我而言,我不得不使用 DispatchQueue:

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

    此线程和其他线程中的其他内容均无效。

    PS:我仔细检查了 textViewDidBeginEditing 在哪个线程上运行,它是主线程,因为所有 UI 都应该在其上运行,所以不知道为什么使用 main.asynch 的小延迟起作用了。

    【讨论】:

    • 这不是延迟,而是下一个运行循环。很可能文本字段的选定范围正在被称为textViewDidBeginEditing 的同一函数修改。因此,通过将其放在队列中,它将在调用者完成后发生。
    • @MichaelOzeryansky 是的,我也这么认为。但这引出了一个问题——手动设置光标位置的正确方法是什么?
    【解决方案3】:

    在您的点设置光标位置:

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

    重置光标位置:

    textView.endFloatingCursor()
    

    注意:此示例适用于 Textview 和 Textfield。

    【讨论】:

    • @Suragch Floating Cursor 是在 textView 或 textField 中设置光标位置的一种方法。
    【解决方案4】:
    let range = field.selectedTextRange
    
    field.text = "hello world"
    
    field.selectedTextRange = range 
    

    【讨论】:

      【解决方案5】:

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

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-04-16
        • 2023-03-14
        • 1970-01-01
        • 2020-12-20
        • 2012-02-12
        • 1970-01-01
        相关资源
        最近更新 更多