2017-05-03 53 views
1

我想在NSView画布中呈现文本。我需要写出三行文字,忽略其他内容。使用提供的矩形String.draw(in:withAttributes)似乎完美的做到这一点。我的代码如下所示:在NSView中写入

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) 

没有调整,我只得到两行文字显示效果:

enter image description here

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

我失去了一些东西?

+0

这是奇怪的是如何在iOS版本的应用程序,相同的代码(与UIFont)似乎工作正常,显示三行。 –

回答

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 
} 
+0

它完美地工作。谢谢! :) –

1

我会尝试在textHeight中添加一个小的三角形 - 双精度非常准确。

+0

我需要添加约4分('textHeight = ... + 4')才能显示第三行。这是一个巨大的差异,我想知道我的lineHeight计算是否正确。在应用的iOS版本上,没有+4调整的相同代码似乎在iOS模拟器中工作。 –

+1

您正在将文本写入精确的印刷边界,但系统可能会调整屏幕显示的文本大小以使文本更清晰(例如,为矢量字体替换屏幕字体)。使用确切的印刷边界也会导致上边界或下边界超出边界的字符出现问题。例如“A环”字符或带有严重口音的大写字母E.你需要找到能够测量特定环境下文本高度的例程......我会看看我是否可以从我的回头机器中抽出时间来回忆它。 –

+2

试试boundingRectWithSize:options:context:(对于NSAttributedString)和boundingRectWithSize:options:attributes:context:(对于NSString) –

2

您正在撰写的文本转换成精确的印刷范围,但该系统可以调整文字的大小的屏幕显示,使文字更清晰(例如代行画面字体为矢量字体)。使用确切的印刷边界也会导致上边界或下边界超出边界的字符出现问题。例如“A环”字符或带有严重口音的大写字母E.

要使用CGContext规则查找文本的范围,这将是绘制在我建议boundingRectWithSize:选项:背景:(用于NSAttributedString)和boundingRectWithSize:选项:属性:背景:(为的NSString)