在 NSView 中编写
Writing in NSView
我正在尝试在 NSView canvas 中呈现文本。我需要写三行文字,忽略其他内容。 String.draw(in:withAttributes) 与提供的 rect 似乎完美地做到这一点。我的代码如下所示:
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)
没有调整,我只渲染了两行文本:
我错过了什么?
我会尝试在 textHeight 中添加一个小的增量 -- 双精度非常准确。
最终,您的文本通过调用构成 Cocoa 文本架构的 类 显示在屏幕上,因此直接从这些 [=17] 获取有关行高的信息是有意义的=].在下面的代码中,我创建了一个 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
}
您正在将文本写入精确的排版边界,但系统可能会调整屏幕显示文本的大小以使文本更清晰(例如,将屏幕字体替换为矢量字体)。使用精确的排版边界也会导致上升或下降超出边界的字符出现问题。例如 "A-ring" 字符或带有重音符号的大写字母 E。
要使用将在其中绘制的 CGContext
规则查找文本的边界,我建议 boundingRectWithSize:options:context:(对于 NSAttributedString)和 boundingRectWithSize:options:attributes:context:(对于 NSString)
我正在尝试在 NSView canvas 中呈现文本。我需要写三行文字,忽略其他内容。 String.draw(in:withAttributes) 与提供的 rect 似乎完美地做到这一点。我的代码如下所示:
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)
没有调整,我只渲染了两行文本:
我错过了什么?
我会尝试在 textHeight 中添加一个小的增量 -- 双精度非常准确。
最终,您的文本通过调用构成 Cocoa 文本架构的 类 显示在屏幕上,因此直接从这些 [=17] 获取有关行高的信息是有意义的=].在下面的代码中,我创建了一个 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
}
您正在将文本写入精确的排版边界,但系统可能会调整屏幕显示文本的大小以使文本更清晰(例如,将屏幕字体替换为矢量字体)。使用精确的排版边界也会导致上升或下降超出边界的字符出现问题。例如 "A-ring" 字符或带有重音符号的大写字母 E。
要使用将在其中绘制的 CGContext
规则查找文本的边界,我建议 boundingRectWithSize:options:context:(对于 NSAttributedString)和 boundingRectWithSize:options:attributes:context:(对于 NSString)