5

I'm pretty sure this is actually a UIKit bug but want to get some input to see if I'm missing something silly here.

Here is the code I have:

// single line with modified line spacing and 2 colors - broken, line spacing is added to the bottom!
UILabel *brokenLabel = [[UILabel alloc] init];
brokenLabel.backgroundColor = [UIColor greenColor];

NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:@"Just some text"];

[attributedString addAttributes:@{NSForegroundColorAttributeName : [UIColor redColor]} range:[attributedString.string rangeOfString:@"text"]];

attributedString = attributedStringFromAttributedStringWithLineSpacing(attributedString, 20, NSTextAlignmentCenter);

brokenLabel.attributedText = attributedString;
[brokenLabel sizeToFit];
brokenLabel.frame = CGRectOffset(brokenLabel.frame, 50, 100);
[self.view addSubview:brokenLabel];
// end

// single line with modified line spacing and 1 color - correct
UILabel *workingLabel = [[UILabel alloc] init];
workingLabel.backgroundColor = [UIColor greenColor];

attributedString = [[NSMutableAttributedString alloc] initWithString:@"Just some text"];

attributedString = attributedStringFromAttributedStringWithLineSpacing(attributedString, 20, NSTextAlignmentCenter);

workingLabel.attributedText = attributedString;
[workingLabel sizeToFit];
workingLabel.frame = CGRectOffset(workingLabel.frame, 200, 100);
[self.view addSubview:workingLabel];
//end

// multiple lines with modified line spacing and 1 color - correct
UILabel *workingLabel2 = [[UILabel alloc] init];
workingLabel2.frame = CGRectMake(0, 0, 100, 0);
workingLabel2.numberOfLines = 0;
workingLabel2.backgroundColor = [UIColor greenColor];

attributedString = [[NSMutableAttributedString alloc] initWithString:@"Just some text"];

attributedString = attributedStringFromAttributedStringWithLineSpacing(attributedString, 20, NSTextAlignmentCenter);

workingLabel2.attributedText = attributedString;
[workingLabel2 sizeToFit];
workingLabel2.frame = CGRectOffset(workingLabel2.frame, 50, 300);
[self.view addSubview:workingLabel2];
//end

// multiple lines with modified line spacing and 2 color - correct
UILabel *workingLabel3 = [[UILabel alloc] init];
workingLabel3.frame = CGRectMake(0, 0, 100, 0);
workingLabel3.numberOfLines = 0;
workingLabel3.backgroundColor = [UIColor greenColor];

attributedString = [[NSMutableAttributedString alloc] initWithString:@"Just some text"];

[attributedString addAttributes:@{NSForegroundColorAttributeName : [UIColor redColor]} range:[attributedString.string rangeOfString:@"text"]];

attributedString = attributedStringFromAttributedStringWithLineSpacing(attributedString, 20, NSTextAlignmentCenter);

workingLabel3.attributedText = attributedString;
[workingLabel3 sizeToFit];
workingLabel3.frame = CGRectOffset(workingLabel3.frame, 200, 300);
[self.view addSubview:workingLabel3];

along with a simple convenience function to change the lineSpacing of an attributed string:

NSMutableAttributedString *attributedStringFromAttributedStringWithLineSpacing(NSAttributedString *string, CGFloat lineSpacing, NSTextAlignment textAlignment)
{
    NSMutableAttributedString *mutable = string.mutableCopy;
    
    NSMutableParagraphStyle *par = [NSMutableParagraphStyle new];
    par.alignment = textAlignment;
    par.lineSpacing = lineSpacing;
    [mutable addAttributes:@{NSParagraphStyleAttributeName : par} range:NSMakeRange(0, mutable.length)];
    return mutable;
}

However, this is what it looks like

image

As you can see, the height of the first label is way too big (or the height that it should be + my custom line spacing, to be precise). When simply adding another color to the first attributed string, it causes the sizeToFit size to increase by adding the lineSpacing below it. I also tried using the boundingRectWithSize: methods on the strings directly and the same issue is visible. So this is not specific to the label sizing code but is an issue with the strings themselves. I don't see any possible reason why this should be happening. Does anyone have any insight?

Community
  • 1
  • 1
Dima
  • 23,484
  • 6
  • 56
  • 83
  • And if you don't add custom line spacing in the first sample - what would be the frame? – sha May 10 '14 at 17:56
  • It works fine without the custom line spacing, or at least it looks like it does. I suspect it still tries to add it at the bottom, but since the value is 0, it would have no real effect and appear fine. – Dima May 10 '14 at 20:06
  • have you solved this? FWIW UITextView does not have this problem at all – bogardon Sep 16 '16 at 18:15
  • I just ran my old sample project with `Xcode 8.0 (8A218a)` and an iOS 10 sim and the problem is still present. My radar is also still open with no updates. – Dima Sep 16 '16 at 19:37

1 Answers1

1

In your Attributes Dictionary add

 [attrDic setObject:@0 forKey:NSBaselineOffsetAttributeName];
Jone Zhu
  • 11
  • 1
  • I tried this in a few different places and unfortunately it does exactly nothing. Can you elaborate and where or how I should be setting this attribute as it pertains exactly to my code? Did you try it with the code I provided above? – Dima Mar 31 '16 at 20:37