菜鸟教程小白 发表于 2022-12-11 19:45:32

ios - 使用属性文本在自定义 UILabel 中定位字符坐标


                                            <p><p>我需要在我的 UILabel 中找到我的字符位置(它有 ParagraphLineSpacing 和多行的 AttributedText),</p>

<p>我有我的角色的索引,但现在我无法从我的索引中获取 X 和 Y 坐标。</p>

<p>我找到了 <a href="http://techqa.info/programming/question/19417776/how-do-i-locate-the-cgrect-for-a-substring-of-text-in-a-uilabel" rel="noreferrer noopener nofollow">http://techqa.info/programming/question/19417776/how-do-i-locate-the-cgrect-for-a-substring-of-text-in-a-uilabel</a> </p>

<p>我翻译成我的 Swift 3.1 代码</p>

<pre><code>func boundingRect(forCharacterRange range: NSRange) -&gt; CGRect {

    let textStorage = NSTextStorage(attributedString: self.attributedText!)
    let layoutManager = NSLayoutManager()
    textStorage.addLayoutManager(layoutManager)
    let textContainer = NSTextContainer(size: bounds.size)
    textContainer.lineFragmentPadding = 0
    layoutManager.addTextContainer(textContainer)
    var glyphRange: NSRange
    // Convert the range for glyphs.

    layoutManager.characterRange(forGlyphRange: range, actualGlyphRange: glyphRange)
    return layoutManager.boundingRect(forGlyphRange: glyphRange, in: textContainer)

}
</code></pre>

<p>但不幸的是,我不能真正使用此代码,因为实际 GlyphRange 询问的是 NSRangePointer,而不是 NSRange,所以我将翻译后的代码更改为</p>

<pre><code>func boundingRect(forCharacterRange range: NSRange) -&gt; CGRect {

    let textStorage = NSTextStorage(attributedString: self.attributedText!)
    let layoutManager = NSLayoutManager()
    textStorage.addLayoutManager(layoutManager)
    let textContainer = NSTextContainer(size: bounds.size)
    textContainer.lineFragmentPadding = 0
    layoutManager.addTextContainer(textContainer)
    //var glyphRange: NSRange

    let a = MemoryLayout&lt;NSRange&gt;.size
    let pointer:NSRangePointer = NSRangePointer.allocate(capacity: a)
    layoutManager.characterRange(forGlyphRange: range, actualGlyphRange: pointer)
    return layoutManager.boundingRect(forGlyphRange: range, in: textContainer)
}
</code></pre>

<p>我不明白是什么</p>

<pre><code> var glyphRange: NSrange
</code></pre>

<p>用法,所以我删除了它,现在代码可以工作了,但结果有 60% 不准确,尤其是当我的角色位于第二行或第三行时。我把这里的翻译搞砸了吗?或者有没有更好的方法来准确地获取我的角色坐标? </p>

<p>我用</p>

<pre><code>NSMakeRange(index, 1)
</code></pre>

<p>让我的参数定位一个特定的字符</p>

<p>=======更新=======</p>

<p>我已经尝试自定义 UITextView 来访问其布局管理器,但不幸的是,如果有 2 行或更多行,位置仍然不准确。 (仅当我的 textView 中只有 1 行时才准确)</p>

<pre><code>class LyricTextView: UITextView {
func boundingRect(forCharacterRange range: NSRange) -&gt; CGRect {
    let inset = self.textContainerInset
    let rect = self.layoutManager.boundingRect(forGlyphRange: range, in: textContainer).offsetBy(dx: inset.left, dy: inset.top)

    return rect
}
}
</code></pre>

<p>我在这个新代码中遗漏了什么吗?它快完成了</p></p>
                                    <br><hr><h1><strong>Best Answer-推荐答案</ strong></h1><br>
                                            <p><p>更容易解决编译错误的方法是使用这个:</p>

<pre><code>var glyphRange = NSRange()
layoutManager.characterRange(forGlyphRange: range, actualGlyphRange: &amp;glyphRange)
</code></pre>

<p>但是,当我尝试它时,我也只能在第一行获得正确的文本矩形。</p>

<p>如果您可以使用 <code>UITextView</code>,您可以访问其布局管理器和文本容器:</p>

<pre><code>@IBOutlet var textView: UITextView!
...

let rect = textView!.layoutManager.boundingRect(
    forGlyphRange: glyphRange, in: textView!.textContainer)
</code></pre>

<p>看来您还需要考虑 TextView 的文本容器插图,因此以下内容对我来说可以在第二行获得文本的边界矩形:</p>

<pre><code>let inset = textView!.textContainerInset
let rect = textView!.layoutManager.boundingRect(
    forGlyphRange: glyphRange, in: textView!.textContainer)
    .offsetBy(dx: inset.left, dy: inset.top)
</code></pre>

<p>如果有人找到适用于 <code>UILabel</code> 的解决方案,我会很感兴趣。</p></p>
                                   
                                                <p style="font-size: 20px;">关于ios - 使用属性文本在自定义 UILabel 中定位字符坐标,我们在Stack Overflow上找到一个类似的问题:
                                                        <a href="https://stackoverflow.com/questions/44200232/" rel="noreferrer noopener nofollow" style="color: red;">
                                                                https://stackoverflow.com/questions/44200232/
                                                        </a>
                                                </p>
                                       
页: [1]
查看完整版本: ios - 使用属性文本在自定义 UILabel 中定位字符坐标