1

我正在尝试在 NSView 画布中呈现文本。我需要写三行文字并忽略超出的内容。带有提供的 rect 的 String.draw(in:withAttributes) 似乎很完美。我的代码如下所示:

func renderText(_ string:String, x:Double, y:Double, numberOfLines: Int, withColor color:Color) -> Double {
    let font = NSFont.boldSystemFont(ofSize: 11)
    let lineHeight = Double(font.ascender + abs(font.descender) + font.leading)
    let textHeight = lineHeight * Double(numberOfLines) + font.leading // three lines
    let textRect = NSRect(x: x, y: y, width: 190, height: textHeight)
    string.draw(in: textRect, withAttributes: [NSFontAttributeName: font, NSForegroundColorAttributeName: color])
    return textHeight
}

renderText("Lorem ipsum...", x: 100, y: 100, numberOfLines: 3, withColor: NSColor.white)

如果不进行调整,我只会渲染两行文本:

在此处输入图像描述

我遵循这些准则:https ://developer.apple.com/library/content/documentation/TextFonts/Conceptual/CocoaTextArchitecture/FontHandling/FontHandling.html#//apple_ref/doc/uid/TP40009459-CH5-SW18

我错过了什么?

4

3 回答 3

2

最终,您的文本通过调用构成 Cocoa 文本架构的类出现在屏幕上,因此直接从这些类中获取有关行高的信息是有意义的。在下面的代码中,我创建了一个NSLayoutManager实例,并将其排版行为属性设置为匹配最终由函数创建的机器使用的排版器的值drawInRect:withAttributes:。然后调用布局管理器的defaultLineHeight方法会为您提供所需的高度值。

lazy var layoutManager: NSLayoutManager = {
    var layoutManager = NSLayoutManager()
    layoutManager.typesetterBehavior = .behavior_10_2_WithCompatibility
    return layoutManager
}()

func renderText(_ string:String, x:Double, y:Double, numberOfLines: Int, withColor color:NSColor) -> Double {
    let font = NSFont.boldSystemFont(ofSize: 11)
    let textHeight = Double(layoutManager.defaultLineHeight(for: font)) * Double(numberOfLines)
    let textRect = NSRect(x: x, y: y, width: 190, height: textHeight)
    string.draw(in: textRect, withAttributes: [NSFontAttributeName: font, NSForegroundColorAttributeName: color])
    return textHeight
}
于 2017-05-03T19:45:22.700 回答
2

您正在将文本写入精确的印刷范围,但系统可能会调整文本的大小以在屏幕上显示以使文本更清晰(例如用屏幕字体替换矢量字体)。使用精确的印刷界限也可能导致字符的上升或下降超出界限。例如“A-ring”字符或带有重音的大写 E。

要使用将在其中绘制的规则找到文本的边界CGContext,我建议 boundingRectWithSize:options:context: (对于 NSAttributedString) 和 boundingRectWithSize:options:attributes:context: (对于 NSString)

于 2017-05-03T23:56:36.870 回答
1

我会尝试在 textHeight 中添加一个小增量——双打非常准确。

于 2017-05-03T15:24:44.490 回答