raindev
raindev

Reputation: 1027

How to retain constraints for a Stack View's child after unhiding?

There's a Stack View which contains three labels and has the following constraints:

storyboard

and the following attributes:

stack view attributes

Label 3 (blue) has a variation: for Compact height size class Installed attribute is disabled (configured via Attributes Inspector). This makes it hidden in the horizontal orientation on iPhone:

installed variation for compact height trait

When the app starts all the labels have correct locations on the screen. After rotating to horizontal orientation and back, Label 3 placed in the top left corner of the Stack View while other labels are aligned correctly:

app after rotation

Xcode View Hierarchy debugger reveals that after reappearing Label 3 doesn't have any UIStackView related constraints and the warning next to it says "Position is ambiguous":

initial constraints for Label 3 missing constraints for Label 3

It seems that the Label 3 have lost all its constraints related to Stack View after being hidden and shown again.

Upvotes: 0

Views: 1355

Answers (2)

DonMag
DonMag

Reputation: 77477

A much, much easier method - set trait variations on the Hidden property.

Here is your layout:

enter image description here

Select the bottom label, and in the Attributes Inspector pane, click the + button next to Hidden:

enter image description here

Change the Variation to:

enter image description here

You now have a new Hidden variation which you can select:

enter image description here

and here's what you get when rotated to wC hC:

enter image description here

As these images show, you even see the results in Storyboard... no waiting for code at run-time.

Upvotes: 1

Gereon
Gereon

Reputation: 17844

You can't use the installed attribute for that, since that adds/removes views to the superview. This is not good enough for a StackView, since it requires subviews to be added using addArrangedSubview().

An easy solution is to create an outlet for your label, and hide/show it upon rotation:

@IBOutlet private var label3: UILabel!

override func willTransition(to newCollection: UITraitCollection, with coordinator: UIViewControllerTransitionCoordinator) {
    super.willTransition(to: newCollection, with: coordinator)

    label3.isHidden = newCollection.verticalSizeClass == .compact
}

Upvotes: 1

Related Questions