简体   繁体   中英

Autolayout height changes when I push a new view controller

Edit: I fixed my problem, but I would be interested in understanding why my fix works. See below.

I use autolayout to build my UITableViewCell s.

The cell is pretty simple with 2 labels (purple and yellow) and a textfield (green).

我的手机

This works fine when displaying the first time. But when I push a new view controller, the view instantly rearranges itself. The purple label gets bigger for whatever reason.

Here is an example where I click the "Parent Account ID" cell to push a new view controller. Notice that as soon as the transition begins, the layout changes. When I come back it is still changed.

细胞动画gif

The items are created with [UILabel new] with no frame.

[self.contentView addSubview:self.textLabel];
[self.contentView addSubview:self.errorLabel];
[self.contentView addSubview:self.textField];

Then the autolayout is created using Masonry .

UIEdgeInsets insets = UIEdgeInsetsMake(3, 15, 3, 15);

[self.textLabel makeConstraints:^(MASConstraintMaker *make) {
    make.left.top.equalTo(self.contentView).insets(insets);
    make.width.priorityLow();
}];

[self.errorLabel makeConstraints:^(MASConstraintMaker *make) {
    make.top.right.equalTo(self.contentView).insets(insets);
    make.left.equalTo(self.textLabel.right).offset(5);
}];

[self.textField makeConstraints:^(MASConstraintMaker *make) {
    make.left.bottom.right.equalTo(self.contentView).insets(insets);
    make.top.equalTo(self.textLabel.bottom).insets(insets);
}];

Notice that I never specify a height because I don't really care about the height. ( as long as it is consistent! )

Any idea why this could change? Thanks

Edit: I found a fix.

I now also set the autolayout properties of contentView .

[self.contentView makeConstraints:^(MASConstraintMaker *make) {
    make.edges.equalTo(self);
}];

I am still interested in understanding why the contentView changes its size!

Your fix works because it enforces a missing constraint.

First, let's start by writing down the constraints that you created using Masonry:

  1. The purple view must be aligned left.
  2. The purple view must be aligned top.
  3. The purple view's width can vary but it's min and max aren't that important.
  4. The yellow view must be aligned right.
  5. The yellow view must be aligned top.
  6. The yellow view's left edge must be 5px away from the purple view's right edge.
  7. The green view must be aligned left.
  8. The green view must be aligned bottom.
  9. The green view must be aligned right.
  10. The green view's top edge must be 0px away from the purple view's bottom edge.

This might seem complete but it allows autolayout to draw your views in many different ways.

Consider the following:


According to the rules you have created above, all three possibilities are true. As you tap on a cell, the layout is invalidated and redrawn. Given that your cell can be drawn a few different ways, it will simply draw itself and satisfy all of your constraints... and it does.

I'll be honest, I'm not 100% sure what make.edges.equalTo(self); does exactly since it is a bit ambiguous. However, one thing is for sure is that it adds the missing constraints you were looking for.

Possible missing constraints are:

  1. The purple view's height must be equal to the green view's height.
  2. The yellow view's height must be equal to the purple view's height.
  3. The green view's height must be equal to the yellow view's height.

Hope this clarifies it for you.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM