Using Swift, I want to get the boundingRect of a glyph, in draw#rect in a UILabel.
The UILabel already has a size (say 300x300 in the example) and qualities such as the text being centered.
class RNDLabel: UILabel {
override func draw(_ rect: CGRect) {
let manager = NSLayoutManager()
let store = NSTextStorage(attributedString: NSAttributedString(
string: text!,
attributes: [NSAttributedString.Key.font: font]))
store.addLayoutManager(manager)
let textContainer = NSTextContainer(size: rect.size)
// note, intrinsicContentSize is identical there, no difference
manager.addTextContainer(textContainer)
let glyphRange = manager.glyphRange(
forCharacterRange: NSRange(location: 0, length: 1),
actualCharacterRange: nil)
let glyphRect = manager.boundingRect(
forGlyphRange: glyphRange, in: textContainer)
print("glyphRect \(glyphRect)")
...context?.addRect(glyphRect), context?.drawPath(using: .stroke)
super.draw(rect)
}
The green square is not correct - it should be more like these red squares!
There seems to be a number of problems:
surely the layoutManager I make, should get the qualities of the UILabel, eg "centered text"? (I believe you can't actually directly access the layoutManager of a UILabel, though?)
should we be using something like CTLineGetOffsetForStringIndex? Is that even possible in draw#rect
notice as well as not having the correct offset, the green box seems the wrong height anyway. (It looks more like a plain old intrinsicContentSize rather than a glyph bounding box.)
How to?
For the record, my overall aim is to move the glyph around, based on the actual glyph box (which of course is different for "y", "X", etc). But in general there are many useful reasons to know the box of a glyph.
drawText(in:)
, it seems to calltextRect(forBounds:)
, which seems to be doing layout by hand. I don't see any layout managers. – Seaver-[UILabel _drawTextInRect:baselineCalculationOnly:]
enough to solve this problem" and hahahahahahah. The Hopper decompile is nearly 1000 lines of pseudo-C code filled with special cases and hahahah. Nah. Maybe it's a fun project, but I wouldn't bother with it. Just build a simple label with TextKit or CoreText that works the way you want, and drag it around. – Seaver