NSAttributedString 绘制位置在 10.13 和 10.14+ 上不同

NSAttributedString draw location different on 10.13 and 10.14+

我使用 NSAttributedStrings draw(in: rect) 将字符串绘制到视图中(普通 NSString 会出现同样的问题)。现在结果似乎与我在 Xcode 中设置的部署目标不同。如果部署目标是 10.13,绘制调用会像这样呈现它

其中红框代表rect。如果我在不触及代码的情况下将部署目标切换到 10.14 或更高版本,相同的绘制调用将呈现如下

创建一个空项目,将 NSWindow 的内容视图 class 设置为 TestView 并在下方创建 class。

class TestView: NSView {

    override func draw(_ dirtyRect: NSRect) {
        NSAttributedString(string: "9", attributes: [
            .font: NSFont.userFixedPitchFont(ofSize: 48)!,
            .foregroundColor: NSColor.labelColor
        ]).draw(in: bounds)
    }
}

现在在 10.13 和 10.14+ 部署目标之间切换,字符串位置将会移动。如果您要检查字符串 .size(),它会在 10.13 上检查 returns 68,在 10.14+ 上检查 58

如何在平台之间保持一致?由于它在包内,因此 DT 可能会有所不同,我想避免不同的代码路径。

此外,10.14+ 版本似乎更“正确”。

我尝试更改字体,发现如果您使用默认系统字体,问题就会消失。这让我相信问题出在 fixed-pitch 字体上——根据 DT,它似乎有不同的 line-height。

通过段落样式设置特定的 line-height 修复了它:

override func draw(_ dirtyRect: NSRect) {
    let paragraphStyle = NSMutableParagraphStyle()
    paragraphStyle.minimumLineHeight = 58
    paragraphStyle.maximumLineHeight = 58
    NSAttributedString(string: "9", attributes: [
        .font: NSFont.userFixedPitchFont(ofSize: 48)!,
        .foregroundColor: NSColor.labelColor,
        .paragraphStyle: paragraphStyle
    ]).draw(in: bounds)
}

我从 Apple 得到的回复:

这是有意为之的行为。部署到 macOS 10.14 或更高版本的应用程序将获得更新的排字器行为,这会影响字形的间距和文本的行高。文本字段高度受文本测量的行高影响。

排字器行为更改更正了一个长期存在的浮点舍入错误,该错误导致将额外高度添加到默认上升器,因此文本尺寸可能比以前小。

请参阅记录此更改的 macOS 10.14 AppKit 发行说明:https://developer.apple.com/documentation/macos-release-notes/appkit-release-notes-for-macos-10_14