在UILabel中的draw#rect中获取字形boundingRect

Fat*_*tie 5 nslayoutmanager drawrect ios swift

使用Swift,我想在UILabel中的draw#rect中获得字形的boundingRect。

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)
    }
Run Code Online (Sandbox Code Playgroud)

在此处输入图片说明

绿色方块不正确-应该更像这些红色方块!

在此处输入图片说明

似乎存在许多问题:

  • 当然,我制作的layoutManager应该获得UILabel的质量,例如“居中文本”吗?(不过,我相信您实际上不能直接访问UILabel的layoutManager?)

  • 我们应该使用像CTLineGetOffsetForStringIndex这样的东西吗?在draw#rect中甚至有可能吗

  • 注意,以及没有正确的偏移量,无论如何,绿色框似乎是错误的高度。(它看起来更像是一个普通的旧的internalContentSize,而不是字形边界框。)

如何?

作为记录,我的总体目标是根据实际字形框移动字形(当然,“ y”,“ X”等也不同)。但是总的来说,有很多有用的原因来了解字形框。

Fat*_*tie 1

事实证明这个问题的答案似乎是:

事实上,无论是否令人惊讶,您基本上无法专门访问UILabel 中的字形信息。

所以实际上你无法在 UILabel 中获得那些字形“实际形状”。

特别是罗布. 指出,一项调查表明,在 UILabel 中,_drawTextInRect:baselineCalculationOnly 完成了这项工作,这是一大堆临时代码。

情况总结似乎是 UILabel 只是早于 NSLayoutManager / Core Text 并且(到目前为止)只是简单地不使用这些现代系统。

只有那些现代系统才能给你这个......

在此输入图像描述

...某种对字形形状的访问。