Ios 使用AttributeText在自定义UILabel中定位字符坐标

Ios 使用AttributeText在自定义UILabel中定位字符坐标,ios,swift3,uilabel,glyph,nslayoutmanager,Ios,Swift3,Uilabel,Glyph,Nslayoutmanager,我需要在UILabel中找到我的角色位置(它有段落行距和带有多行的AttributeText) 我已经得到了我角色的索引,但现在我无法从索引中获得X和Y坐标 我找到了这个 我翻译成我的Swift 3.1代码 func boundingRect(forCharacterRange range: NSRange) -> CGRect { let textStorage = NSTextStorage(attributedString: self.attributedText!)

我需要在UILabel中找到我的角色位置(它有段落行距和带有多行的AttributeText)

我已经得到了我角色的索引,但现在我无法从索引中获得X和Y坐标

我找到了这个

我翻译成我的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)

}
但是,不幸的是,我无法真正使用此代码,因为实际上,phrange要求的是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)
}
用法,所以我删除了它,现在代码可以工作了,但是结果是60%不准确,特别是当我的字符位于第二行或第三行时。我把这里的翻译搞砸了吗?或者有没有更好的方法来精确地获取角色坐标

我用

NSMakeRange(index, 1) 
让我的参数定位一个特定字符

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

我已尝试使用自定义UITextView访问其布局管理器,但不幸的是,如果有2行或更多行,位置仍然不准确。(仅当我的文本视图中只有一行时才准确)


我是不是在新代码中遗漏了什么?即将完成

对于编译错误,更容易的修复方法是使用以下方法:

var glyphRange = NSRange()
layoutManager.characterRange(forGlyphRange: range, actualGlyphRange: &glyphRange)
然而,当我尝试它时,我也只能为第一行的文本获得正确的矩形

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

@IBOutlet var textView: UITextView!
...

let rect = textView!.layoutManager.boundingRect(
    forGlyphRange: glyphRange, in: textView!.textContainer)
您似乎还需要考虑文本视图的文本容器插入,因此以下内容对我来说非常有用,可以为第二行的文本获取边界矩形:

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

如果有人找到一个适用于
UILabel

的解决方案,我会很感兴趣。是否可以让我们知道您搜索字符坐标的目的?为什么
var glyphRange:NSRange
。在Objective-C中,它使用的是
&glyphRange
,因此方法是
layoutManager。characterRange()
实际上给了它一个值。这就是为什么。这与
[myUIColor getRed:&red-green:&green:&blue-blue:&blue-alpha:&alpha]使用的“逻辑”相同
@elk\u cloner我需要在我的特定角色上方画和弦,例如:“我爱上了你的[G]形状”我必须在“shape”@Larme的单词顶部画
G
,是的,我知道方法是
layoutManager.characterRange()
,但我不知道如何填写实际的phrange参数?可能的重复我想只要我得到预期的结果就可以了,明天我会试试这个。我尝试了UITextView,但如果有两行或更多行,它仍然无法得到准确的位置。我已经更新了我的代码,所以我可能还是错过了什么@三卤甲烷
@IBOutlet var textView: UITextView!
...

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