2017-05-03 80 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)