myieh
myieh

Reputation: 79

Can't shrink UILabel to fit content when rotating

I'm having trouble getting my UILabel to resize properly using Auto Layout. Basically I want my label to always be sized just big enough to match its content. Here are some pictures to demonstrate what I mean.

enter image description here

enter image description here

Notice the extra top and bottom padding in landscape orientation. I don't want that. I want the label to shrink vertically so that it just contains its content.

I have a top constraint of 33 to top layout guide, a leading constraint of 75 to superview, and a trailing constraint of 75 to superview.

So again my goal is to allow resizing of the label based on orientation, but to have the label only encompass its content without any padding.

Thanks.

Upvotes: 3

Views: 2036

Answers (3)

Mesbah
Mesbah

Reputation: 171

Looks like only updating the preferredMaxLayoutWidth on any change (rotation, xib resizes etc), that effects the size, will do.

Example: I designed a view in IB with iPhone screen size like this:

iPhone Portrait

To make it work in landscape, add following code in your view controller:

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

-(void)updateLabels
{
    [self updateLabelPreferredMaxLayoutWidthToCurrentWidth:self.label1];
    [self updateLabelPreferredMaxLayoutWidthToCurrentWidth:self.label2];
    [self updateLabelPreferredMaxLayoutWidthToCurrentWidth:self.label3];
}

- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
    [super willAnimateRotationToInterfaceOrientation:toInterfaceOrientation duration:duration];

    [self updateLabels];
}

Basically we are just changing the preferredMaxLayoutWidth of each label in willAnimateRotationToInterfaceOrientation, as the size is being changed there. Outcome is:

iPhone Landscape

If you want to support multiple display size, just call the updateLabels in viewDidAppear like this:

-(void)viewDidAppear:(BOOL)animated
{
    [self updateLabels];
}

This is because, I designed a single xib with iPhone display size, but want to support multiple display size. After the view is already appeared, the exact size of all the elements is calculated.

iPad Portrait Demo with same xib and adjustment code in viewDidAppear:

iPad Portrait Demo

Hope this helps.

Upvotes: 2

sammalfix
sammalfix

Reputation: 320

Edit: here is a better answer than mine below: https://stackoverflow.com/a/15927392/3414722
It should do exactly what you want and it's fine to be used with Auto Layout.


You could call sizeToFit on the label every time the orientation is changed. In theory, sizeToFit isn't supposed to be used together with Auto Layout, but it should give you the effect you want. Here is the code you need in your view:

- (void)updateViewConstraints {
    [super updateViewConstraints];

    [self.label sizeToFit];
}

- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
    [super willAnimateRotationToInterfaceOrientation:toInterfaceOrientation duration:duration];

    [self.view setNeedsUpdateConstraints];
}

Upvotes: 1

P. Sami
P. Sami

Reputation: 2207

What you need is a flexible constraint for the bottom of it. So let's say make the bottom constraint to be bigger than or equal to 0 and set the priority of it to 100. Then select the UILabel and change its Vertical Content Hugging priority to 99. This way the content hugging gets precedence over the bottom distance and the padding will be gone in all orientations.

Upvotes: 2

Related Questions