Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Resize container UIView to match height of visible subview after hiding mutually exclusive subview

ParentView contains ChildView1 and ChildView2. These subviews are of different heights.

ChildView1 is taller than ChildView2. Only one subview is shown, e.g., if ChildView1 is visible then ChildView2 is hidden. Both ChildView1 and ChildView2 use custom XIBs.

Both subviews "drive" the height of ParentView, that is the AutoLayout constraints are wired such that ParentView is as tall as ChildView1 or ChildView2, and no taller.

The problem is hiding ChildView1 and showing ChildView2 does not "shrink" ParentView to match the height of ChildView2. It remains at the height of the taller subview, ChildView1.

Calling sizeToFit() and setNeedsLayout() does not change things.

How to force ParentView to match ChildView2's height when ChildView1 is hidden?

like image 374
Crashalot Avatar asked Feb 07 '23 04:02

Crashalot


2 Answers

Hidden views still participate in layout. You need to deactivate the constraints on the hidden view in addition to hiding it.

If your deployment target is iOS 9 or later, you can make the parent be a UIStackView. A stack view automatically ignores its hidden children during layout.

UPDATE

You don't need separate outlets for all the constraints. You just need two outlet collections. You can connect one outlet collection to multiple objects. Demo:

creating outlet collections

The collections end up connected to multiple objects in the storyboard:

view controller connections

Then you can activate or deactivate a collection of constraints with one statement:

class ViewController: UIViewController {

    @IBOutlet var pinkConstraints: [NSLayoutConstraint]!
    @IBOutlet var greenConstraints: [NSLayoutConstraint]!

    func showPink() {
        NSLayoutConstraint.deactivateConstraints(greenConstraints)
        NSLayoutConstraint.activateConstraints(pinkConstraints)
    }

    func showGreen() {
        NSLayoutConstraint.deactivateConstraints(pinkConstraints)
        NSLayoutConstraint.activateConstraints(greenConstraints)
    }

}
like image 174
rob mayoff Avatar answered Feb 09 '23 16:02

rob mayoff


You can set the parent view to hold the same size as the child views

// Match to childView1
CGSize size = childView1.frame.size;
[parentView setFrame:CGRectMake(0,0,size.width,size.height)];

Or conversely

// Match to childView2
CGSize size = childView2.frame.size;
[parentView setFrame:CGRectMake(0,0,size.width,size.height)];
like image 40
Luffy Avatar answered Feb 09 '23 18:02

Luffy