具有动态高度的容器视图,具有自动布局的UIScrollView

时间:2014-12-05 13:09:06

标签: ios autolayout

我有一个UIScrollView,嵌套在一个内容视图中,它有两个嵌套的子视图,一个具有已知高度的常规UIView,以及一个动态高度取决于内容的容器视图。像这样:

Main View hierarchy

视图如下所示:

Main View

我的约束设置如下:

滚动视图受限于其超级视图的尾随,前导,顶部和底部边缘(即视图)

内容视图受限于其超级视图的尾随,前导,顶部和底部边缘(即滚动视图) 它的宽度约束也等于主视图(即视图),因此滚动视图的宽度与屏幕宽度相同。

顶视图受限于其超级视图的前沿,尾随和上边缘(即内容视图)

容器视图受限于其超级视图的尾随,前导和下边缘(内容视图) 它的上边缘也被限制在顶视图的底边。

Container View的视图层次结构如下所示:

Content View heirarchy

Content View

左上角的标签被约束到其超级视图的尾部,前导和上边缘。 右下角的标签被限制在其超视图的尾部,前部和底部边缘。 顶部标签对底部标签有垂直约束。为了我的测试,我已经使这个垂直约束特别大(1000分)。

这应该为内容视图提供~1000点的高度。

我的理解是现在为容器视图解析了高度,内容视图将调整为顶视图的高度+容器视图的高度。

但IB抱怨如下:

IB

它希望调整容器视图的大小并使其高度为0.如果我给容器视图一个明确的高度,那么一切都按预期工作但这不是我需要的,因为容器视图可以根据其动态更改内容大小。

感谢任何帮助!

3 个答案:

答案 0 :(得分:34)

我找到的两件事帮助我解决了同样的问题。

问题1:容器高度

我希望容器视图自己调整大小,但IB希望在容器视图上有一个显式高度。由于IB对视图的内容一无所知,因此无法知道容器视图的内容可以自行调整大小。最简单的方法是从容器视图的Size Inspector中设置Placeholder Intrinsic Content Size

Size Inspector

这有效地使IB在不应用任何高度限制的情况下快乐。另一个选择是在容器上添加“在构建时删除”高度约束。

问题2:子视图控制器视图的高度

子视图控制器的根视图默认使用AutoresizingMask,这是任何UIViewController中最顶层视图的标准。我的解决方案是在添加子视图控制器时禁用AutoresizingMaskprepareForSegue的使用。在视图控制器中尝试以下操作:

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    super.prepare(for: segue, sender: sender)

    if let childViewController = segue.destination as? ChildViewControllerClass {
        childViewController.view.translatesAutoresizingMaskIntoConstraints = false
    }
}

在父视图中进行更改可确保如果在UINavigationController内的其他位置重新使用子视图,则视图的大小将正确。

在我做出更改之前,我一直在使AutoLayout错误与名为UIView-Encapsulated-Layout-Height的约束发生冲突,我认为这是在AutoresizingMask视图根据基于UIViewController的布局派生的约束的名称

答案 1 :(得分:5)

您必须在UIScrollView中提供足够的约束信息,以便它可以计算其contentSize。对于您的情况,您必须为容器视图提供高度约束。您可以IBOutlet高度约束并相应地更新其值。

答案 2 :(得分:0)

在您的情况下,如果您想要摆脱有关Container高度的IB警告应为零。您可以使用适合您的任何常量值设置高度约束,并将其作为占位符(它将在构建时删除。)