7
votes

Currently I have 3 views inside 1 view (which is pinned to leading edge and trailing edge of superview).

The 3 views look like this currently:

3 views with equal widths

However, in some cases, I wish to hide the indigo view, but still keep the last 2 the same widths like so: 2 views with equal widths with indigo view hiding

How can I achieve this with autolayout? Or how can I achieve this using IBOutlets for constraints?

3
Have you tried creating an IBOutlet and then using the .hidden property? - Matthew Bradshaw
@MatthewBradshaw what would the IBOutlet be connected to? - Bob
Connect the view you want to manipulate programmatically to an IBOutlet by control dragging into the assistant editor. Then manipulate that outlet. The .hidden property is a boolean. Check out this tutorial developer.apple.com/library/ios/referencelibrary/GettingStarted/… - Matthew Bradshaw
Have you tried using UIStackView? - tktsubota
@tktsubota I'm supporting iOS 8 as well so that's not an option unfortunately. Stackview would make it so much easier. - Bob

3 Answers

8
votes

If the deployment target is iOS9 or later, it is recommended to use UIStackView as the enclosing view. Setting isHidden to true on any view arranged in the UIStackView will not only make the view hidden, but also will the stack view re-organize all the non-hidden views to fill up the space that was taken by the hidden views. This behavior could be tuned by adjusting distribution on UIStackView.


Tj3n's answer works, but it has a drawback that you have to use magic numbers in your code and set constraint properties both in code and IB.

IMHO, a better solution would be setting up all the constraints in IB with different priorities and activating/deactivating them in code. Try this:

  1. Set the leading/trailing constraints as you did before.
  2. Set equal width constraints for all three views with priority high.
  3. Set 0 width constraints for all three views with priority required, but leave them deactivated in IB. And connect them to IBOutlets in code just as connecting views.
  4. Activate any of the 0 width constraints to collapse the view you want, and later deactivate them to expand.

Note that just with 1 and 2 in place, you can achieve the equal-width view layout. And with 3 and 4, you can collapse/expand any of the views selectively.

2
votes

Its pretty easy, you can create equal width constraint A for the 3 view, set its priority is 998, then create another single width constraint B1, B2, B3 for them, set priority is 997, if you want to hide any of the 3 view, set B constraint's constant to 0, and up its priority to 999, then call self.view.layoutIfNeeded, the view will hide and others will scale

The test constraint is the width constraint of the gray view: enter image description here

0
votes

If it is always the indigo view which can be hidden, you should solve your problem by adding this constraints :

Indigo view : leading to superview + trailing to purpleView + width constraint

Purple view : same width as grayView

Gray View : leading to purpleView + trailing to superview

It should looks like this :

Constraints

View

And if you change the width property of your indigoView, all should follow correctly.

Hope that help you.