2017-05-26 72 views
1

我需要找到我的UILabel我的性格位置(它有ParagraphLineSpacing和AttributedText具有多),定位在自定义的UILabel字符协调与attributedText

我有我的性格的指数,但现在我不能让X和我的索引中的Y坐标。

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

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

我PARAMS找到一个特定的字符

======= =======修订

我曾尝试定制的UITextView到访问其布局管理器,但不幸的是,如果有两行或更多行,该位置仍然不准确。 (只有在我的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 
    } 
} 

我在这段代码中丢失了什么吗?这是越来越接近完成

+0

是否有可能让我们知道您的搜索字符统筹的目的是什么? –

+0

为什么'var glyphRange:NSRange'。在Objective-C中,它使用'&glyphRange',所以方法是'layoutManager.characterRange()'实际上给它一个值。这就是为什么。这与'[myUIColor getRed:&red green:&green blue:&blue alpha:&alpha];'是一样的“逻辑”。 – Larme

+0

@elk_cloner我需要在我的特定角色上方绘制和弦,例如:“我爱上了你的[G]形状” 我必须在“形状”字样的顶部正好画出“G” @Larme 是的,我知道该方法是'layoutManager.characterRange()',但我很困惑如何填充actualGlyphRange PARAMS? –

回答

0

一种更容易修复你的编译错误是使用这样的:

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有效的解决方案,我会感兴趣。

+0

我认为它会好,只要我得到了预期的结果,明天我会试试这个 –

+0

我已经尝试过UITextView,如果有2行或更多,它仍然无法获得准确的位置。我已经更新了我的代码,所以也许我仍然错过了一些东西? @thm –