菜鸟教程小白 发表于 2022-12-11 18:34:45

ios - 第一个矩形(对于 :) returns wrong value in UITextField


                                            <p><p>我正在尝试使用语法高亮来标记用户输入的错误。 </p>

<p>遵循 <a href="https://stackoverflow.com/questions/11486072/get-x-and-y-coordinates-of-a-word-in-uitextview" rel="noreferrer noopener nofollow">Get X and Y coordinates of a word in UITextView</a> 中的建议我的代码非常适合 UITextView</p>

<p>但是,我现在正在尝试为 UITextField 做类似的事情并且遇到了麻烦。</p>

<p>UITextField 和 UITextView 都符合 UITextInput 并且定位矩形所需的所有方法都适用于两者。</p>

<p>这是 UITextView 的函数</p>

<pre><code>func findRect(forTextMatching match:String, in textView:UITextView) -&gt; 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
}
</code></pre>

<p>在测试应用程序中运行它并突出显示返回的矩形,如下所示:</p>

<p> <a href="/image/jRJvt.png" rel="noreferrer noopener nofollow"><img src="/image/jRJvt.png" alt="enter image description here"/></a> </p>

<p>现在尝试用 UITextField 做同样的事情:</p>

<pre><code>func findRect(forTextMatching match:String, in textField:UITextField) -&gt; 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
}
</code></pre>

<p>第一个问题是 UITextField.beginningOfDocument 为 nil,除非该字段是第一响应者。这很容易处理,因此额外的行变成了 becomeFirstResonder 和 resignFirstResponder。</p>

<p>在测试应用程序中运行它并突出显示返回的矩形,如下所示:</p>

<p> <a href="/image/Wq4KQ.png" rel="noreferrer noopener nofollow"><img src="/image/Wq4KQ.png" alt="enter image description here"/></a> </p>

<p>返回的矩形略有偏移。</p></p>
                                    <br><hr><h1><strong>Best Answer-推荐答案</ strong></h1><br>
                                            <p><p>这似乎是 UITextField 的一个错误。在调试中检查 View 层次结构,在 UITextField 下有一个额外的 View ,类型为 UIFieldEditor,具有框架原点 (7,4)。返回的 rect 似乎与此 View 相关,而不是 UITextField。</p>

<p>原来你可以作为 UITextField 的 editRect 来访问这个框架。</p>

<p>UITextField 的修改函数:</p>

<pre><code>func findRect(forTextMatching match:String, in textField:UITextField) -&gt; 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)
            {
                var rect = textField.firstRect(for: textRange)

                // firstRect is actually relative to editingRect, not textField
                let top = textField.editingRect(forBounds: textField.bounds).origin.y
                let left = textField.editingRect(forBounds: textField.bounds).origin.x
                rect = CGRect(x: rect.origin.x+left, y: rect.origin.y+top, width: rect.width, height: rect.height)

                return rect
            }
      }
    }

    return nil
}
</code></pre>

<p>产生正确的结果:</p>

<p> <a href="/image/BXPmK.png" rel="noreferrer noopener nofollow"><img src="/image/BXPmK.png" alt="enter image description here"/></a> </p></p>
                                   
                                                <p style="font-size: 20px;">关于ios - 第一个矩形(对于 :) returns wrong value in UITextField,我们在Stack Overflow上找到一个类似的问题:
                                                        <a href="https://stackoverflow.com/questions/45910145/" rel="noreferrer noopener nofollow" style="color: red;">
                                                                https://stackoverflow.com/questions/45910145/
                                                        </a>
                                                </p>
                                       
页: [1]
查看完整版本: ios - 第一个矩形(对于 :) returns wrong value in UITextField