gpt4 book ai didi

ios - 使用 attributedText 在自定义 UILabel 中定位字符坐标

转载 作者:塔克拉玛干 更新时间:2023-11-02 22:10:21 25 4
gpt4 key购买 nike

我需要在我的 UILabel 中找到我的角色位置(它有 ParagraphLineSpacing 和带多行的 AttributedText),

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

我找到了这个http://techqa.info/programming/question/19417776/how-do-i-locate-the-cgrect-for-a-substring-of-text-in-a-uilabel

我翻译成我的 Swift 3.1 代码

func boundingRect(forCharacterRange range: NSRange) -> 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)

}

但是,不幸的是,我不能真正使用这段代码,因为 actualGlyphRange 询问 NSRangePointer,而不是 NSRange,所以我将翻译后的代码更改为

func boundingRect(forCharacterRange range: NSRange) -> 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<NSRange>.size
let pointer:NSRangePointer = NSRangePointer.allocate(capacity: a)
layoutManager.characterRange(forGlyphRange: range, actualGlyphRange: pointer)
return layoutManager.boundingRect(forGlyphRange: range, in: textContainer)
}

我不明白什么

 var glyphRange: NSrange 

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

我用

NSMakeRange(index, 1) 

让我的参数定位一个特定的字符

=======已更新=======

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

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

return rect
}
}

我在这个新代码中遗漏了什么吗?快完成了

最佳答案

一个更简单的修复编译错误的方法是使用这个:

var glyphRange = NSRange()
layoutManager.characterRange(forGlyphRange: range, actualGlyphRange: &glyphRange)

但是,当我尝试时,我也只能在第一行得到正确的文本矩形。

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

@IBOutlet var textView: UITextView!
...

let rect = textView!.layoutManager.boundingRect(
forGlyphRange: glyphRange, in: textView!.textContainer)

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

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

如果有人找到适用于 UILabel 的解决方案,我会很感兴趣。

关于ios - 使用 attributedText 在自定义 UILabel 中定位字符坐标,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44200232/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com