Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

UILabel text layout when wrapping is "wrong" in iOS 7

Tags:

uilabel

ios7

The screen shot below is in iOS 7. label1 (yellow, top) is drawn with the text origin below the top left of the its frame and clipped at the bottom. In iOS 5/6 the text origin is the top left of the label frame. label2 and label3 render and layout as expected.

enter image description here

Here is the code to generate this view:

- (void)loadView
{
    UIView *view = [[UIView alloc] initWithFrame:UIScreen.mainScreen.applicationFrame];
    view.backgroundColor = UIColor.blueColor;
    self.view = view;

    UILabel *label1 = [UILabel new];
    label1.backgroundColor = UIColor.yellowColor;
    label1.font = [UIFont systemFontOfSize:16.0f];
    label1.numberOfLines = 0;
    label1.lineBreakMode = NSLineBreakByWordWrapping;
    label1.frame = CGRectMake(50, 100, 200, 18);
    label1.text = @"This text is too long to fit on one line.";
    [self.view addSubview:label1];

    UILabel *label2 = [UILabel new];
    label2.backgroundColor = UIColor.greenColor;
    label2.font = [UIFont systemFontOfSize:16.0f];
    label2.numberOfLines = 0;
    label2.lineBreakMode = NSLineBreakByWordWrapping;
    label2.frame = CGRectMake(50, 150, 200, 36);
    label2.text = @"This text is too long to fit on one line.";
    [self.view addSubview:label2];

    UILabel *label3 = [UILabel new];
    label3.backgroundColor = UIColor.orangeColor;
    label3.font = [UIFont systemFontOfSize:16.0f];
    label3.numberOfLines = 0;
    label3.lineBreakMode = NSLineBreakByWordWrapping;
    label3.frame = CGRectMake(50, 200, 200, 18);
    label3.text = @"This text is short.";
    [self.view addSubview:label3];
}

QUESTION: Why is this different in iOS 7 and what label properties do I need to change to have the text in label1 render starting from the top left of its frame as expected.

like image 938
XJones Avatar asked Feb 16 '23 02:02

XJones


1 Answers

I figured it out. Rather than delete my question, I'll answer it here so if anyone else runs into this they know what to do.

The label frames are hardcoded to specific sizes. In the case of label1, the height is 18. This bound is not tall enough to render a line of text with a system font at 16 points. iOS 5/6 apparently top align the text rect whereas in iOS 7 this causes unpredictable behavior. This fix is to ensure the label bounds are tall enough to display at least one line of text.

The sample code in the question was for the purposes of reproducing this problem. My actual app code calculates label heights based on desired number of lines with various other views positioned around the label so the frame is changed dynamically at run time. I fixed the problem in my app by ensuring the minimum label height can fit a single line of text.

like image 139
XJones Avatar answered Feb 20 '23 12:02

XJones