Shu Suzuki
Shu Suzuki

Reputation: 1184

How to take larger height as its parent height in AutoLayout

I have a view which contains two views vertically. Let's say upper view is A and lower view is B. B contains 2 views horizontally. Lets's say they are B-1 and B-2. So it looks like

  |------------------|
  |    A             |
  |                  |
  |------------------|
  |    B             |  (There is no margin around B-1 and B-2)
  ||-------||-------|| 
  || B-1   || B-2   ||  (B-1 and B-2 has intrinsic content size)
  ||-------||-------||
  |----------------- |

I want to make A's height bigger as long as B-1 and B-2 can show their contents (by AutoLayout). B-1 and B-2's heights may be different so I have to set B's height to larger height of the two.

My first thought is to return intrinsic size of B. In B's intrinsicContentSize method I can calculate which size is bigger and return its size.

It seems it is working but I felt a little awkward because if I add another view like B-3, I have to rewrite the code. I would like to write a clean AutoLayout constraints to fill the requirements.

Is there any better solution to solve this by AutoLayout?

Upvotes: 0

Views: 68

Answers (2)

Ken Thomases
Ken Thomases

Reputation: 90531

You haven't said how you want B-1 and B-2 arranged vertically within B when they have different heights. For example, they might be both top aligned, both vertically centered, both bottom aligned, or something else.

Anyway, the usual approach is to directly specify the rules:

  1. B.top == B1.top
  2. B.top == B2.top
  3. B1.bottom <= B.bottom
  4. B2.bottom <= B.bottom
  5. B.height == 0 @ priority 200
  6. superview.top == A.top
  7. A.bottom == B.top
  8. B.bottom == superview.bottom

I have chosen to have B-1 and B-2 top aligned. That's achieved by the first two constraints. The next two make sure that B is tall enough to show the full height of both of them. Constraint 5 makes sure that B is no taller than necessary. Constraints 6 through 8 make A and B vertically adjacent and fill the superview.

Of course, you'll need horizontal constraints, too, but I think you can handle that.

You should not have B compute an intrinsic content size. The size of a container view is not intrinsic, it's extrinsic. It's derived from the sizes of other things, not its own (non-view) content.

Upvotes: 1

Darren
Darren

Reputation: 25619

There are two options:

  1. Set an Equal-Heights constraint between B1 and B2. They will both take the height of the largest intrinsic height between the two views.

  2. Use a pair of >= and == constraints.

For option 2, the == constraint must have a lower priority than the >= constraint. For example:

  • B1: Top space to container == 0 @ 250 priority
  • B1: Top space to container >= 0 @ 1000 priority
  • B2: Top space to container == 0 @ 250 priority
  • B2: Top space to container >= 0 @ 1000 priority

"B" will then take largest height of B1 and B2.

Upvotes: 0

Related Questions