Используя Swift, я хочу получить boundingRect глифа в draw#rect в UILabel.
UILabel уже имеет размер (скажем, 300x300 в примере) и качества, такие как центрирование текста.
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)
}
Зеленый квадрат не правильный - он должен быть больше похож на эти красные квадраты!
Кажется, есть ряд проблем:
конечно, layoutManager, который я делаю, должен получить качества UILabel, например, «текст по центру»? (Я полагаю, что вы не можете получить прямой доступ к layoutManager UILabel?)
мы должны использовать что-то вроде CTLineGetOffsetForStringIndex? Это вообще возможно в draw#rect
обратите внимание, а также не имея правильного смещения, зеленая рамка все равно кажется неправильной высоты. (Это больше похоже на старый добрый innerContentSize, чем на ограничивающую рамку глифа.)
Как?
Для справки, моя общая цель состоит в том, чтобы перемещать глиф, основываясь на фактическом поле глифа (которое, конечно, отличается для «y», «X» и т. д.). Но вообще есть много полезных причин знать поле глифа.
drawText(in:)
, он вроде бы вызываетtextRect(forBounds:)
, который вроде бы делает верстку вручную. Я не вижу никаких менеджеров компоновки. - person Rob Napier   schedule 15.07.2019-[UILabel _drawTextInRect:baselineCalculationOnly:]
достаточно, чтобы решить эту проблему и хахахахахах. Декомпиляция Хоппера — это почти 1000 строк кода на псевдо-C, наполненных особыми случаями и хахахами. Неа. Может быть, это забавный проект, но я бы не стал с ним заморачиваться. Просто создайте простую метку с помощью TextKit или CoreText, которая работает так, как вы хотите, и перетащите ее. - person Rob Napier   schedule 15.07.2019