franciscojma86
franciscojma86

Reputation: 337

Constraints in iOS 8

I am creating a table header view with two UILabels. The constraints look like this: enter image description here The top UILabel is attached to the top, leading and trailing edges of the container. The bottom UILabel has the leading and trailing edges aligned to the top label, and the bottom edge to the bottom of the container. There is also a vertical spacing constraint between the two UILabels. All views translatesAutoresizingMaskIntoConstraints have been set to NO of course. BTW, the whole thing is made in code.

I calculate the height of the UIView by getting the intrinsic content size of each label and padding so that I can create the rect of the container view and add it to the UITableView. Like this: -(float)calculateHeightwithMaxWidth:(float)maxWidth { float totalHeight = 0; const float containerPadding = 30; const float maxHeight = 1000; maxWidth = maxWidth - containerPadding; UIFont *nameFont = [UIFont fontWithName:@"AvenirNext-Regular" size:18]; UIFont *descriptionFont = [UIFont fontWithName:@"AvenirNext-Regular" size:13]; CGSize nameSize = [_productNameLabel.text gsSizeWithFont:nameFont withMaximumSize:CGSizeMake(maxWidth, maxHeight)]; CGSize descriptionSize = [_productDescriptionLabel.text gsSizeWithFont:descriptionFont withMaximumSize:CGSizeMake(maxWidth, maxHeight)]; totalHeight = nameSize.height + descriptionSize.height + containerPadding; return totalHeight; }

This code works perfectly in iOS 7 and has been working for several versions. Now that I'm testing in iOS 8 I get a crash with unsatisfying constraints. If I see the constraints of the view before calling layoutIfNeeded everything looks great, but after calling it I see two new constraints, which are the width and height constraints of the container view. I never created this constraints, and in iOS 7 never needed to.

Even after creating these constraints myself to fix this, I get even more errors trying to break them. Am I missing something? Did the logic for constraints change in iOS 8?

Thanks!

Upvotes: 0

Views: 1750

Answers (1)

matt
matt

Reputation: 534893

The problem is that you are asking for too much precision. You don't know exactly what height the auto layout system will give (you are just adding up some numbers that you think will give the same result), and so when you assign the header view a fixed height, if it doesn't match the system's own calculation perfectly, right down to the last decimal place, the constraints can't be satisfied. You should never have been doing it that way in the first place; you are mixing apples with oranges (manual calculation with the system's autolayout). The system may, for example, apply rounding of which you can know nothing (in order to keep the rects integral, etc.). Who knows what it does? I'm amazed that this ever worked.

You have two much better choices:

  • Wrap the pair of views in a container view (looks like you've done that) and just ask the container view for its systemLayoutSizeFittingSize. This tells you exactly what the system will do. In other words, instead of you calculating (which is hit or miss), ask the system to calculate.

  • Even better, allow yourself some slack: make one of the height spacer constraints an inequality or a lower priority, so that when you apply your fixed height that constraint has permission to grow or shrink.

Upvotes: 1

Related Questions