dMurdZ
dMurdZ

Reputation: 1079

No fixed height in interface builder, constraint predicament

The screen I'm trying to create is very simple. I have two UIViews stacked atop one another. The top UIView, topView, has height of 40px, and the UIView below, botView, takes up the rest of the screen. However, sometimes topView should not appear and I want botView to take up the entirety of the screen.

What I've tried is setting width, leading/trailing space on both views. Then topView gets distance to top layout guide, botView gets distance to bottom layout guide, and then an additional constraint for vertical spacing between topView and botView. But this results in xcode yelling at me that I haven't set a height or y constraint on one of the views. Of course, I can't set a height constraint because I do not want either of them to be fixed height.

I'm sure there must be an elegant constraint solution here that I just can't seem to figure out. Thoughts?

Upvotes: 0

Views: 1544

Answers (3)

Brandon
Brandon

Reputation: 2427

There are a couple of ways to do this. One option

In IB lay out your views. Then pin top view 0 px from the top, bottom, left, and right. Specify a height constraint of 40 px as well. To easily do this click on your view, then in the lower right hand corner click on the button that looks like | + |. Click on the dotted red lines to specify the constraints. See image:

enter image description here

Do the same for the other view. Don't specify a height for this view because it's height is dependent on the 40 px view for its height. Next find the height constraint for the 40 px view. You can can use the assistant editor to control drag an outlet to you view controller just like you would with a UIButton or any other IB element. When you want to hide your 40 px view set the variables constant property to 0. When you want to show it again set it back to 40.

self.topViewHeightConstraint.constant = 0;

enter image description here

The other option you could go with is to pin the top view 0 px to the top, left and right. Don't provide a bottom constraint but specify the height as 40 px. For the bottom view add add a left, right, and bottom constraint of 0 px. For the top constraint add a constraint of 40 px from the top superview. Again add an outlet for the most recent top constraint and when you want the view to be larger set that constraint to be 0.

Upvotes: 1

timothykc
timothykc

Reputation: 2235

An alternative: In IB, add a distance to top layout guide constraint for BOTVIEW (it will be 40...) Then click-drag this constant to the VC to create a NSLayoutConstraint property.see also here

Now, upon the condition that hides topView, you set self.myConstraint.constant = 0; This will force botView to resize to meet the condition of being 0 from the top.

You may have to clear your current constraints to get rid of errors, but this should give the desired behavior.

As for "topView" like Tom Ahh suggests, go ahead and give it a height constraint of 40 and pin it to the top as you're already doing.

Upvotes: 0

tomahh
tomahh

Reputation: 13651

If topView should always be 40px height, then add a constraint for the height of topView.

As for botView, you can keep the current constraint that says its top has to be correlated with the bottom of topView. But add another constraint for bottom view with a priority lower than required that says it should be 0px away from the top of its superview. This way, when you remove topView from the containing view, botView's constraint related to topView will be deleted, and therefore will satisfy the lower priority constraint.

And if you want to push back topView in, recreate the botView to topView distant constraint with required priority.

Upvotes: 1

Related Questions