在自动布局中设置约束,以便 UIView 包装可见的子项

Posted

技术标签:

【中文标题】在自动布局中设置约束,以便 UIView 包装可见的子项【英文标题】:Set constraints in autolayout so UIView wraps visible children 【发布时间】:2017-01-22 13:24:15 【问题描述】:

我正在努力实现以下目标。

我有一个

--> MainView
      --> UIImageView 200x200
      --> UILabel W:200(max) , H: Variable 
      --> UILabel W:Variable , H: 20 

mainView 中的所有视图都是依次排列的。 现在我正在尝试设置 autoLayout,以便 mainView 的高度取决于其子项,

例如,如果我将 ImageView 设置为隐藏,那么它应该同时包裹 UILabels 等。

如何设置 autoLayout 约束,以便主视图对其子视图具有“环绕”效果。

【问题讨论】:

那么你是想让标签放大以填充主视图的高度还是缩小主视图以保持标签的高度相同? 【参考方案1】:

实现此目的的简单方法是使用UIStackView (WWDC 2015 session video)。在这种情况下,纯自动布局要复杂得多。

假设您想将孩子垂直放置,左对齐:

控制后沿

在每个子节点的后沿和父节点的后沿之间添加一个大于或等于 0 的约束。这将导致最宽的孩子将父母的后缘向右推。这些约束应该具有非常高的优先级。

您将需要另一个约束来防止布局不明确。通过三个尾随约束,可以确保父视图的宽度不小于最宽的子视图。您还必须限制父视图的宽度不大于最宽子视图的宽度。只需向父级添加一个宽度约束,常量为 0 且优先级非常低。

我喜欢把这个低优先级的宽度约束想象成一个橡皮筋,试图将后缘尽可能地向左拉。最宽子视图的大于或等于零约束阻止它进一步拉动。

隐藏视图没有效果,因为隐藏视图仍然参与布局计算。您需要保留对大于或等于约束的引用,并在隐藏子项时禁用相应的约束以使其后沿脱离方程。

控制高度

子项的高度可能由视图的固有内容大小定义。从概念上讲,Autolayout 引擎会根据内容拥抱和内容压缩阻力的设置向视图添加宽度和高度约束。

对于具有固有高度尺寸的视图,将有两个隐藏的高度约束:一个用于内容拥抱,一个用于内容压缩。拥抱将高度限制为小于或等于固有高度。抗压性将高度限制为大于或等于固有高度。如果两者都可以满足,则视图的高度完全等于固有高度。内容压缩阻力和内容拥抱的优先级可以分别设置,以便细粒度地控制何时打破约束。

如果孩子被隐藏,我们可以利用这些知识让 parentView 的高度缩小。我们需要为父母的身高设置一个“橡皮筋约束”:

使用低优先级将父级的高度限制为零,例如 2。

每当您隐藏视图时,请确保将该视图的垂直压缩阻力优先级降低到小于橡皮筋约束优先级的值,例如 1。现在橡皮筋压倒了压缩阻力约束,导致该视图的高度视图折叠,父视图相应地缩小。取消隐藏视图以反转效果时,请务必将该优先级提高到大于橡皮筋约束的值。

【讨论】:

【参考方案2】:

现在我正在尝试设置自动布局,因此 mainView 的高度取决于它的子视图

您不能仅通过约束来做到这一点。自动布局本身通常不会“从内到外”调整视图的大小,即通过使用其子视图约束。 (例外情况是特殊的自调整视图,如滚动视图的容器视图或表格视图自调整单元格。)

但是,您可以在代码中。这就是systemLayoutSizeFitting 的用途。您必须在 superview 上执行手动布局,但您可以通过调用此方法轻松完成。

【讨论】:

【参考方案3】:

每个 UI 元素需要 4 个约束来推断其边界和位置。 x 位置、y 位置、heightwidth

假设您需要将 mainView 缩小到 UILabels 的高度,为 mainView 设置除 heightConstarint 之外的所有三个约束。即,为xywidth 设置约束。现在为三个子视图设置所有四个约束。必须为所有三个子视图的高度显式设置一个常量值。现在 mainView 的高度将从子视图的高度推断出来。要包装标签,请在需要时将代码中的UIImageViewheightConstraint 设置为零。可以将UIImageViewheightconstraintIBOutlet 设置为零。

【讨论】:

以上是关于在自动布局中设置约束,以便 UIView 包装可见的子项的主要内容,如果未能解决你的问题,请参考以下文章

在 viewWillAppear 中设置约束

代码中设置的自动布局约束未出现在界面生成器中

在代码中设置自动布局约束时出现奇怪的问题

“隐藏”具有自动布局子视图的 UIView

从 Storyboard iOS 导出或打印自动布局约束

我们如何在 uitableview 单元格中设置标签约束?