Hello,
As of Catalina (10.15.2 for this writing) and XCode 11 (11.3 11C29), the function boundingRectWithSize in AppKit is returning a different value than in previous versions of XCode. I don't see any explanation within the various release notes for this change. Unfortunately, this is impacting previous UI layouts, designs, and constraints for existing applications. At first, I thought it might be a difference between the now deprecated function and the new API, however both return the same results across all tests. Another thought was that perhaps light and dark modes were impacting the fonts rendering, but this also appeared to be a non-factor. Additionally, this appears to affect all fonts and font sizes, but these differences are not a common ratio. Additionally, using the latest API's NSStringDrawingContext, there are no differences between the dimensions of the drawingContext.totalBounds and the boundingRect either. Both are returning the same result, which is different between Xcode 10 and Xcode 11.
Is this a bug or regression? Or is this a known, documented change? What is the recommended approach to handle and account for this difference?
The code used for the test (latest API, not deprecated):
- (void)testBoundingRect {
NSString* string = @"The quick brown fox jumps over the lazy dog";
NSFont* font = [NSFont fontWithName:@"Tahoma" size:17];
NSDictionary *stringAttributes =
[NSDictionary dictionaryWithObjectsAndKeys:
font, NSFontAttributeName,
[NSColor textColor], NSForegroundColorAttributeName,
nil];
NSSize maxSize = NSMakeSize(CGFLOAT_MAX, 0.0);
// Latest API
NSStringDrawingContext *drawingContext = [[NSStringDrawingContext alloc] init];
NSRect boundingRect =
[string boundingRectWithSize:maxSize
options:NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading
attributes:stringAttributes
context:drawingContext];
NSLog(@"Height: %f", boundingRect.size.height);
// XCTAssert(boundingRect.size.height == 26); // Expected (MacOS 10.14-, XC 10.3-)
// XCTAssert(boundingRect.size.height == 21); // Actual (MacOS 10.15, XC 11+)
NSLog(@"Height: %f", drawingContext.totalBounds.size.height);
// XCTAssert(drawingContext.totalBounds.size.height == 26); // Expected (MacOS 10.14-, XC 10.3-)
// XCTAssert(drawingContext.totalBounds.size.height == 21); // Actual (MacOS 10.15, XC 11+)
}
The results:
XC 9.4.1 (Mojave) Target API 10.13 | XC 10.3 (Mojave) Target API 10.13 | XC 10.3 (Mojave) Target API 10.14 | XC 10.3 (Catalina) Target API 10.13 | XC 10.3 (Catalina) Target API 10.14 | XC 11.3 (Catalina) Target API 10.14 | XC 11.3 (Catalina) Target API 10.15 | |
Light Mode | |||||||
boundingRect.size.height | 26 | 26 | 26 | 26 | 26 | 21 | 21 |
Dark Mode | |||||||
boundingRect.size.height | 26 | 26 | 26 | 26 | 26 | 21 | 21 |