i need to locate my character location in my UILabel (it has ParagraphLineSpacing and AttributedText with multiline),
i have got my character's index, but now i can't get X and Y coordinate from my index.
i Have found this http://techqa.info/programming/question/19417776/how-do-i-locate-the-cgrect-for-a-substring-of-text-in-a-uilabel
and i translated to my Swift 3.1 code
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)
}
but, unfortunately, i can't really use this code because actualGlyphRange ask NSRangePointer, not NSRange, so i changed my translated code to
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)
}
i don't understand what
 var glyphRange: NSrange 
usage, so i removed it and now the code is working, but the result is 60% not accurate especially when my character located on the second line or the third line. Do i messed up the translation here? Or are there any better method to get my character coordinate accurately?
i use
NSMakeRange(index, 1) 
for my params to locate one specific character
=======UPDATED=======
I have tried custom UITextView to access its layout Manager, but unfortunately, the position is still inaccurate if there are 2 lines or more. (only accurate if there is only 1 line in my textView)
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
  }
}
Am i missing something in this new code? It is getting nearly done
 
                        
An easier fix for your compilation error would be to use this:
However, when I tried it, I also could only get correct rectangles for text on the first line.
If using a
UITextViewis ok for you, you have access to its layout manager and text container:It seems you also need to take into account the text view's text container inset so the following worked for me to get a bounding rect for text on the second line:
I'd be interested if somebody finds a solution that works for
UILabel.