Получение глифа boundingRect в draw # rect в UILabel.Жирная щедрость - PullRequest
5 голосов
/ 08 июля 2019

Используя 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)
    }

enter image description here

Зеленый квадрат неправильный - он должен быть больше похож на эти красные квадраты!

enter image description here

Кажется, есть ряд проблем ...

  • конечно, компоновщик, который я создаю, должен получить качества UILabel, например, «центрированный текст»? (Я полагаю, что вы на самом деле не можете получить прямой доступ к layoutManager UILabel?)

  • мы должны использовать что-то вроде CTLineGetOffsetForStringIndex? Это возможно даже в розыгрыше # rect

  • обратите внимание, так как не имея правильного смещения, зеленое поле все равно кажется неправильной высотой. (Это больше похоже на обычный старый тип intrinsicContentSize, а не на ограничивающий прямоугольник глифа.)

Как?

FTR Моя общая цель состоит в том, чтобы перемещать глиф вокруг, основываясь на фактической коробке глифа (которая, конечно, отличается для "y", "X" и т. Д.). Но в целом есть много полезных причин, чтобы узнать коробку глифа.

Ответы [ 2 ]

0 голосов
/ 17 июля 2019

Ваш первоначальный вопрос является своего рода вопросом, потому что он говорит о двух совершенно противоположных вещах.

  • С одной стороны, вы говорите UILabel.

  • С другой стороны, вы используете такие термины, как NSLayoutManager и NSTextStorage и NSTextContainer - стек TextKit.

Это противоположности, поскольку UILabel не рисуется со стеком TextKit.То, что вы просите сделать, это как пытаться поднять лист бумаги с помощью магнита;магниты действительно поднимают вещи, но они поднимают магнитные материалы, и бумага не относится к числу таких.Конечно, UILabel должен рисовать каким-то детерминистическим способом, но что такое таким образом, совершенно неизвестно и непрозрачно и не имеет ничего общего с TextKit.

С другой стороны, UITextView,или представление, что вы рисуете сами, используя TextKit, использует , использует TextKit, и теперь все инструменты TextKit применяются.Поэтому то, что вы просите сделать, было бы намного проще, если бы это было UITextView (или представлением, которое вы рисуете сами, используя TextKit).

Это не должно сильно влиять на внешний вид интерфейса.UITextView может работать так же, как UILabel (сделать его нередактируемым и неконтролируемым), но с тем важным отличием, что весь стек текстового набора отображается напрямую.Так вот с чего я начну.Я один из тех, кто предпочитает использовать фреймворк, а не бороться с ним.

0 голосов
/ 15 июля 2019

Оказывается, ответ на этот вопрос:

На самом деле, на удивление или нет, у вас в основном нет доступа к информации о глифах в UILabel, в частности.

Таким образом, вы реально не можете получить эти глифы "реальных фигур" в UILabel.

В частности, РобН. указал, что исследование показало, что в UILabel, _drawTextInRect: baselineCalculationOnly выполняет свою работу, и это большая куча специального кода.

Краткое изложение ситуации может показаться, что UILabel просто предшествует NSLayoutManager / Core Text и (пока что) просто не использует эти современные системы.

Только те современные системы дают вам это ...

enter image description here

... своего рода доступ к фигурам по глифам.

...