Incorrect size returned by UILabel/NSAttributedString

Originator:diego.sanchez
Number:rdar://20161020 Date Originated:2015-03-13
Status:Open Resolved:
Product:iOS SDK Product Version:iOS 8
Classification:Other Bug Reproducible:Always
 
boundingRectWithSize in NSAttributedString and sizeThatFits in UILabel are inconsistent for some strings.

Steps to Reproduce:
- (void)stringSizeBug {
    NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];
    paragraphStyle.lineSpacing = 2;
    paragraphStyle.alignment = NSTextAlignmentCenter;
 
    NSDictionary *attributes = @{
        NSForegroundColorAttributeName : [UIColor whiteColor],
        NSParagraphStyleAttributeName : paragraphStyle,
        NSFontAttributeName : [UIFont systemFontOfSize:12]
    };
 
    NSDictionary *attributes2 = @{
        NSParagraphStyleAttributeName : paragraphStyle,
        NSFontAttributeName : [UIFont systemFontOfSize:12]
    };
 
    NSAttributedString *part1 = [[NSAttributedString alloc] initWithString:@"Add me here" attributes:attributes];
    NSAttributedString *part2 = [[NSAttributedString alloc] initWithString:@" − Get seen by millions!" attributes:attributes2];
    NSMutableAttributedString *text = [[NSMutableAttributedString alloc] initWithAttributedString:part1];
    [text appendAttributedString:part2];
 
    // Bug 1 in NSAttributedString
    NSLog(@"%@", NSStringFromCGSize([text boundingRectWithSize:CGSizeMake(251, 100) options:NSStringDrawingUsesFontLeading | NSStringDrawingUsesLineFragmentOrigin context:nil].size));  // {201.70800000000003, 16.315999999999999}
    NSLog(@"%@", NSStringFromCGSize([text boundingRectWithSize:CGSizeMake(226, 100) options:NSStringDrawingUsesFontLeading | NSStringDrawingUsesLineFragmentOrigin context:nil].size));  // {201.70800000000003, 14.315999999999999}
 
    // Bug 2 in UILabel
    UILabel *label = [[UILabel alloc] init];
    label.numberOfLines = 0;
    label.attributedText = text;
    NSLog(@"%@", NSStringFromCGSize([label sizeThatFits:CGSizeMake(251, 100)]));  // {202, 16.5}
    NSLog(@"%@", NSStringFromCGSize([label sizeThatFits:CGSizeMake(226, 100)]));  // {202, 14.5}
}

Or https://gist.github.com/diegosanchezr/8c740548fd51400ea34c

Expected Results:
I expect to get a consistent sizeThatFits/boundingRectWithSize if I provide enough size to fit.

Actual Results:
I get different sizes for two rects that can contain perfectly the string.

Version:
iOS 8

Notes:
It does not affect iOS 7.
It seems to be taking into account lineSpacing = 2, but only one line is required. It seems to be required that both parts in the attributed string have different arguments. In the example it's just the color.

Configuration:
iOS 8

Comments


Please note: Reports posted here will not necessarily be seen by Apple. All problems should be submitted at bugreport.apple.com before they are posted here. Please only post information for Radars that you have filed yourself, and please do not include Apple confidential information in your posts. Thank you!