Reputation:
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".
Upvotes: 5
Views: 327
Reputation: 402
The reply I got from Apple:
This is intended behavior. Apps deploying to macOS 10.14 or later will get the newer typesetter behavior, which affects the spacing of glyphs and the line height of text. The text field height is affected by the line height of the text measurement.
The typesetter behavior change corrected a long-standing floating point rounding error that resulted in extra height being added to the default ascender, so the text may measure smaller than previously.
Please refer to macOS 10.14 AppKit release notes documenting this change: https://developer.apple.com/documentation/macos-release-notes/appkit-release-notes-for-macos-10_14
Upvotes: 1
Reputation: 299
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)
}
Upvotes: 2