Ios – AutoLayout with hidden UIViews

autolayoutiosobjective c

I feel like it's a fairly common paradigm to show/hide UIViews, most often UILabels, depending on business logic. My question is, what is the best way using AutoLayout to respond to hidden views as if their frame was 0x0. Here is an example of a dynamic list of 1-3 features.

Dynamic features list

Right now I have a 10px top space from the button to the last label, which obviously won't slide up when the the label is hidden. As of right now I created an outlet to this constraint and modifying the constant depending on how many labels I'm displaying. This is obviously a bit hacky since I'm using negative constant values to push the button up over the hidden frames. It's also bad because it's not being constrained to actual layout elements, just sneaky static calculations based on known heights/padding of other elements, and obviously fighting against what AutoLayout was built for.

I could obviously just create new constraints depending on my dynamic labels, but that's a lot of micromanaging and a lot of verbosity for trying to just collapse some whitespace. Are there better approaches? Changing frame size 0,0 and letting AutoLayout do its thing with no manipulation of constraints? Removing views completely?

Honestly though, just modifying the constant from context of the hidden view requires a single line of code with simple calculation. Recreating new constraints with constraintWithItem:attribute:relatedBy:toItem:attribute:multiplier:constant: seems so heavy.

Edit Feb 2018: See Ben's answer with UIStackViews

Best Answer

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.

Related Topic