隐藏互斥子视图后调整容器 UIView 的大小以匹配可见子视图的高度

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

ParentView 包含 ChildView1 和 ChildView2。这些子视图具有不同的高度。

ChildView1 比 ChildView2 高。仅显示一个子视图,例如,如果 ChildView1 可见,则隐藏 ChildView2。 ChildView1 和 ChildView2 都使用自定义 XIB。

两个子视图 "drive" ParentView 的高度,即 AutoLayout 约束的连接方式使得 ParentView 与 ChildView1 或 ChildView2 一样高,而不是更高。

问题是隐藏 ChildView1 而显示 ChildView2 与 "shrink" ParentView 不匹配 ChildView2 的高度。它保持在较高的子视图 ChildView1 的高度。

调用 sizeToFit()setNeedsLayout() 并没有改变。

如何在ChildView1隐藏时强制ParentView匹配ChildView2的高度?

您可以将父视图设置为与子视图保持相同的大小

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

或相反

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

隐藏视图仍然参与布局。除了隐藏它之外,您还需要停用隐藏视图的约束。

如果您的部署目标是 iOS 9 或更高版本,您可以将父级设置为 UIStackView。堆栈视图在布局期间自动忽略其隐藏的子项。

更新

您不需要针对所有约束的单独出口。您只需要两个出口系列。您可以将一个插座集合连接到多个对象。演示:

集合最终连接到故事板中的多个对象:

然后您可以使用一条语句激活或停用一组约束:

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)
    }

}

通过在 ParentView 和 ChildView1/ChildView2 之间插入中间视图解决了问题。这样,ChildView1 驱动其包含视图的高度,而不是 ParentView,这与 ChildView2 相同。也许不是最干净的,但它正在工作。 Rob 关于使用 UIStackView 的建议似乎很理想,但它只需要放弃对 iOS 8 的支持,这对于应用程序来说目前并不实用。