I use NSAttributedString
s draw(in: rect)
to draw a string into a view (same problem occurs with a plain NSString
). Now the outcome seems to be different to what deployment target I set in Xcode. If the deployment target is 10.13
, the draw call renders it like this
where the red box represents rect
. If I switch the deployment target to 10.14
or above without touching the code, the same draw call renders like this
Create an empty project, set the NSWindow
s content view class to TestView
and create the class below.
class TestView: NSView {
override func draw(_ dirtyRect: NSRect) {
NSAttributedString(string: "9", attributes: [
.font: NSFont.userFixedPitchFont(ofSize: 48)!,
.foregroundColor: NSColor.labelColor
]).draw(in: bounds)
}
}
Now switch between 10.13 and 10.14+ deployment target and the string location will shift. If you would check the strings .size()
it returns 68
on 10.13 and 58
on 10.14+.
How do I make this consistent between platforms? Since it is inside a package the DT could vary, and I want to avoid different code paths.
Moreover the 10.14+ version seems more "correct".
I tried changing the font and noticed that the issue disappears if you're using the default system font. This led me to believe that the problem lies with the fixed-pitch font — it appears to have a different line-height depending on the DT.
Setting a specific line-height via a paragraph style fixes it:
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)
}