Michiel van Oosterhout
Michiel van Oosterhout

Reputation: 23094

How to keep correct layout for UIStackView's subview after the subview re-appears after device rotation?

Hi have a UIStackView for which I have deselected the Installed property for compact heights:

enter image description here

Interface Builder shows the element in portrait mode and hides the element in landscape mode. When I run the app in the iPhone simulator, initially in portrait mode the element is rendered correctly (second row of buttons):

enter image description here

The element disappears after rotating right. But after rotating left again back to portrait mode, the element is rendered incorrectly (see top left of the screen):

enter image description here

Do I need to programmatically take care of the element's layout after is appears again? If so, where can I find documentation to help get me started with this?

Upvotes: 2

Views: 1509

Answers (2)

Michiel van Oosterhout
Michiel van Oosterhout

Reputation: 23094

Comparing the parent view's subviews and arrangedSubviews properties indicates that iOS adds the view to the former, but not to the latter. (This is when iOS takes care of adaptive layout based on variations of the 'installed' checkbox for different traits, as specified in the attribute inspector.)

So this specific subview needs to be inserted back into the arranged subviews. I added this override to the main view controller (layout is the stack view, secondaryRow is the row of buttons that is removed/added depending on the screen's height):

override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()

    if let index = layout.subviews.index(of: secondaryRow) {
        layout.insertArrangedSubview(secondaryRow, at: index)
    }
}

I'm sure it can be generalised, perhaps to synchronise all UIStackViews subviews and arrangedSubviews when the layout has changed.

Upvotes: 2

Rahul
Rahul

Reputation: 2100

I think you need to redraw the views again when you change the orientation by overriding viewWillTransistion method.

override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
    super.viewWillTransition(to: size, with: coordinator)

    // When orientations changes draw the layout again
    // by invalidating the current layout of the views
    // For Example, if I want to redraw for UIStackView I will use
    stackView.setNeedsLayout()
}

Upvotes: -1

Related Questions