AutoLayout with hidden UIViews?

My personal preference for showing/hiding views is to create an IBOutlet with the appropriate width or height constraint.

I then update the constant value to 0 to hide, or whatever the value should be to show.

The big advantage of this technique is that relative constraints will be maintained. For example let's say you have view A and view B with a horizontal gap of x. When view A width constant is set to 0.f then view B will move left to fill that space.

There's no need to add or remove constraints, which is a heavyweight operation. Simply updating the constraint's constant will do the trick.


The solution of using a constant 0 when hidden and another constant if you show it again is functional, but it is unsatisfying if your content has a flexible size. You'd need to measure your flexible content and set a constant back. This feels wrong, and has issues if content changes size because of server or UI events.

I have a better solution.

The idea is to set the a 0 height rule to have high priority when we hide the element so that it takes up no autolayout space.

Here's how you do that:

1. set up a width (or height) of 0 in interface builder with a low priority.

setting width 0 rule

Interface Builder won't yell about conflicts because the priority is low. Test the height behavior by setting the priority to 999 temporarily (1000 is forbidden to mutate programmatically, so we won't use it). Interface builder will probably now yell about conflicting constraints. You can fix these by setting priorities on related objects to 900 or so.

2. Add an outlet so you can modify the priority of the width constraint in code:

outlet connection

3. Adjust the priority when you hide your element:

cell.alertTimingView.hidden    = place.closingSoon != true
cell.alertTimingWidth.priority = place.closingSoon == true ? 250 : 999