获取字形背景的一致大小

时间:2019-01-04 17:56:52

标签: ios swift textkit

大家好-我是TextKit的新手,正在尝试围绕特定属性绘制背景和边框。我已经很接近了,但是还没有找到不会产生大小不一致的方法,这似乎很糟糕。这是我的第一个建议:

class MyLayout: NSLayoutManager {
    override func drawBackground(forGlyphRange glyphsToShow: NSRange, at origin: CGPoint) {
        super.drawBackground(forGlyphRange: glyphsToShow, at: origin)

        guard let storage = textStorage else {
            return
        }
        guard let context = UIGraphicsGetCurrentContext() else {
            return
        }

        var codeBlockRect: CGRect? = nil
        enumerateLineFragments(forGlyphRange: glyphsToShow) { (rect, usedRect, container, subRange, stop) in
            var effectiveRange = NSRange()
            let attributes = storage.attributes(at: subRange.location, effectiveRange: &effectiveRange)
            storage.enumerateAttribute(.inlineCodeBlock, in: subRange) { (value, attributeRange, stop) in
                guard value != nil else {
                    return
                }
                var background = self.boundingRect(forGlyphRange: attributeRange, in: container)
                background.origin.x += origin.x
                background.origin.y += origin.y

                context.setFillColor(UIColor.lightGrey.cgColor)
                context.setStrokeColor(UIColor.mediumGrey.cgColor)
                context.stroke(background)
                context.fill(background)
            }
        }
    }
}

产生以下结果:

单行文本:
Single line of text

多行文本:
Multiple lines of text

如您所见,大小之间大约有3个像素的差异。我想这是因为boundingRect,如文档所述:

  

返回将给定glyphRange中的字形完全包围的最小边界矩形

但是我还没有找到一种方法可以使我的数字更接近所需的数字。我的理想情况是每个矩形都将具有完全相同的高度。

让我知道是否需要更多信息。

更新

我想这可能与我们使用的专有字体有关,所以我将所有内容都更改为使用UIFont.systemFont,这没有任何区别。

1 个答案:

答案 0 :(得分:0)

我在这里找到了解决方法-我没有将inlineCodeBlock定义为背景,而是将其定义为自定义下划线样式。

这样做使我可以覆盖drawUnderline(forGlyphRange:underlineType:baselineOffset:lineFragmentRect:lineFragmentGlyphRange:containerOrigin:)

有了这些,我就可以使用baselineOffset获得一致的定位。