为字形背景获得一致的大小

getting consistent sizing for glyph backgrounds

大家好 – 我是 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)
            }
        }
    }
}

产生这些结果:

单行文字:

多行文字:

如您所见,那里的尺寸大约有 3 个像素的差异。我想这是因为 boundingRect,正如文档所说:

Returns the smallest bounding rect which completely encloses the glyphs in the given glyphRange

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

如果需要更多信息,请告诉我。

更新

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

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

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

一旦我有了它,我就可以使用 baselineOffset 来获得一致的定位。