firstRect(for :)在UITextField中返回错误的值

时间:2017-08-27 23:17:23

标签: ios swift

我尝试进行语法突出显示以标记用户输入上的错误。

根据Get X and Y coordinates of a word in UITextView中的建议,我的代码适用于UITextView

但是,我现在正试图为UITextField做类似的事情并遇到麻烦。

UITextField和UITextView都符合UITextInput,找到rect所需的所有方法都适用于这两种方法。

这是UITextView的功能

func findRect(forTextMatching match:String, in textView:UITextView) -> CGRect? {
    if let text = textView.text,
       let range = text.range(of: match)
    {
        let offset1 = text.distance(from: text.startIndex, to: range.lowerBound)
        let offset2 = text.distance(from: text.startIndex, to: range.upperBound)

        if let pos1 = textView.position(from: textView.beginningOfDocument, offset: offset1),
        let pos2 = textView.position(from: textView.beginningOfDocument, offset: offset2)
        {
            if let textRange = textView.textRange(from: pos1, to: pos2)
            {
                textView.selectedTextRange = textRange
                let rect = textView.firstRect(for: textRange)
                return rect
            }
        }
    }

    return nil
}

在测试应用程序中运行此命令并突出显示返回rect,如下所示:

enter image description here

现在尝试使用UITextField执行相同的操作:

func findRect(forTextMatching match:String, in textField:UITextField) -> CGRect? {
    if let text = textField.text,
       let range = text.range(of: match)
    {
        let offset1 = text.distance(from: text.startIndex, to: range.lowerBound)
        let offset2 = text.distance(from: text.startIndex, to: range.upperBound)

        // beginningOfDocument is nil unless textField is first responder
        textField.becomeFirstResponder()
        defer {
            textField.resignFirstResponder()
        }

        if let pos1 = textField.position(from: textField.beginningOfDocument, offset: offset1),
            let pos2 = textField.position(from: textField.beginningOfDocument, offset: offset2)
        {
            if let textRange = textField.textRange(from: pos1, to: pos2)
            {
                textField.selectedTextRange = textRange
                var rect = textField.firstRect(for: textRange)

                return rect
            }
        }
    }

    return nil
}

第一个问题是UITextField.beginningOfDocument是nil,除非该字段是第一响应者。这很容易处理,因此需要额外的行来成为FirstResonder和resignFirstResponder。

在测试应用中运行此操作并突出显示返回的rect,如下所示:

enter image description here

返回的rect稍微偏移。

1 个答案:

答案 0 :(得分:0)

好像这是UITextField的错误。在调试中检查视图层次结构在UITextField下有一个额外的视图,类型为UIFieldEditor,具有帧起点(7,4)。返回的rect似乎与此视图相关,而不是UITextField。

事实证明,您可以将此框架作为UITextField的editRect访问。

UITextField的修改后的函数:

192.168.0.1-255

产生正确的结果:

enter image description here