Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

UILabel sizeToFit and constraints

Is there any simple way which can help me to change position of dependent views dynamically using their content size?

I want to show several views in column which all have varying content. And I want them to be placed one after another (I've created layout using constraints which looks like this)

initial layout

But whenever I change content of labels and call sizeToFit, system seems to ignore layout.

after size to fit call

At the moment I'm interested only in height property, I know that constraining rect can be used too and in the past I wrote many categories on UIView to change sizes dynamically (I guess everyone did). But maybe there is a simple way which I don't know?

like image 462
Nik Avatar asked Apr 10 '13 13:04

Nik


2 Answers

-sizeToFit should not be called if you are using auto-layout. That's part of the 'old' system.

It looks like IB has inserted explicit heights into your constraints (the vertical bars next to the labels indicate this). Try selecting the labels and hitting Cmd+= to clear these.

For multiline labels you will also need to do the following in your view controller to make everything work correctly when rotating/resizing the view:

- (void)updateLabelPreferredMaxLayoutWidthToCurrentWidth:(UILabel *)label
{
    label.preferredMaxLayoutWidth =
        [label alignmentRectForFrame:label.frame].size.width;
}

- (void)viewDidLayoutSubviews
{
    [super viewDidLayoutSubviews];

    [self updateLabelPreferredMaxLayoutWidthToCurrentWidth:self.label1];
    [self updateLabelPreferredMaxLayoutWidthToCurrentWidth:self.label2];
    [self updateLabelPreferredMaxLayoutWidthToCurrentWidth:self.label3];

    [self.view layoutSubviews];
}

Multiline labels expose one of the weaknesses of auto-layout. We have to update preferredMaxLayoutWidth to force the label to reflow and adjust its height, otherwise if the view is resized/rotated, auto-layout does not realize the label needs to be reflowed and resized.

like image 154
Mike Weller Avatar answered Nov 01 '22 11:11

Mike Weller


If you still want to use Auto Layout Constraint for your Label. This is a solution:

[self.lblBadgeValue sizeToFit];
self.constraintWidthBadgeLabel.constant =  self.lblBadgeValue.frame.size.width;
[self.lblBadgeValue needsUpdateConstraints];
[self.lblBadgeValue layoutIfNeeded];
  • Explain more:
  • sizeToFit -> make label fit height, width with content of it.
  • So in runtime you need to update constraint height, or width for label
  • After that you need to say for compiler know that what need update constraint.
  • And in the end you need to call layout if have change on constraint.
like image 2
Linh Nguyen Avatar answered Nov 01 '22 11:11

Linh Nguyen