使用自动布局在子视图动态更改后调整 Superview 的大小

看在上帝的份上,我不能掌握这个调整大小的管理视图的窍门。

我有一个具有4个 UILabels.2函数的 UIView *superview作为其他两个函数的头。

所有4个中的内容都是来自数据库的动态内容。

SizeToFitSizeThatFits:(CGSize)UIView systemLayoutSizeFittingSize:,通过 UILayoutFittingCompressedSize或者 UILayoutFittingExpandedSize

我以编程的方式使用自动布局,并且将 Superview 高度设置为等于或大于一个虚拟数字。

我在哪里和如何使用这些 SizeToFitsizeThatFits:(CGSize)UIView systemLayoutSizeFittingSize:,通过或者 UILayoutFittingCompressedSize或者 UILayoutFittingExpandedSize。我在这里读了很多关于栈的建议,但是最后什么也没有得到。

我需要重新计算某个特定地方的超视图的约束吗。可以在它的控制器类中将高度设置为“ be@property”,然后删除并读取它吗? 自动取款机我试着把所有的东西都放在任何地方。我仍然得到相同的大小与虚拟高度和文本漂浮在外面的结果。即使在 subview 上设置了 clipsToBound。

我抓我的头发. . 帮助

78999 次浏览

如果你正在使用自动布局,这里是你需要做的:

  1. 确保没有向任何子视图添加固定宽度和/或高度约束(取决于要动态调整的尺寸)。其思想是让每个子视图的内在内容大小决定子视图的高度。UILabel带有4个自动隐式约束,这些约束(优先级低于要求)试图将标签的框架保持在适合所有文本内部所需的精确大小。

  2. 确保每个标签的边缘严格地连接到彼此的边缘和它们的管理视图(带有必要的优先级约束)。你要确保,如果你想象一个标签的大小增长,这将迫使其他标签为它腾出空间,最重要的是迫使超视图以及扩展。

  3. 只在超视图中添加约束来设置它的位置,而不是大小(至少不是您希望它动态调整大小的维度)。请记住,如果正确设置了内部约束,它的大小将由所有子视图的大小决定,因为它的边缘以某种方式连接到它们的边缘。

就是这样。您不需要调用 sizeToFitsystemLayoutSizeFittingSize:来使其工作,只需加载您的视图并设置文本,应该就可以了。系统布局引擎将为您进行计算以解决约束。(如果需要的话,您可能需要在 superview 上调用 setNeedsLayout... ... 但是这不应该是必需的。)

使用容器视图

在下面的示例中,我有一个30x30的图像,而且 UILabel比包含占位符文本的视图小。我需要的包含视图至少是一样大的图像,但它需要增长,以包含多行文本。

在可视化格式中,内部容器如下所示:

H:|-(15.0)-[image(30.0)]-(15.0)-[label]-(15.0)-|
V:|[image(30.0)]|
V:|[label(>=30.0)]|

然后,设置包含视图以匹配标签的高度。现在,包含视图将调整标签的大小。

正如@mileyborg 在他的回答中指出的那样,将内容严格地连接到 Superview 会通知布局引擎,简单的容器视图应该会导致它的增长。

黄色对齐矩形

如果需要黄色对齐矩形,请在方案的运行参数列表中添加 -UIViewShowAlignmentRects YES

UILabel that is multi-line

随着 iOS9中 Stack View 的引入,这一点变得非常简单。在视图中使用堆栈视图来包含调整大小的所有内容,然后简单地调用

view.setNeedsUpdateConstraints()
view.updateConstraintsIfNeeded()
view.setNeedsLayout()
view.layoutIfNeeded()

然后你可以通过调用

view.systemLayoutSizeFittingSize(UILayoutFittingCompressedSize)

如果您需要计算视图所需的确切大小。

这几乎紧跟在@mileyborg 的回答之后,并附带了一个具体的例子。

enter image description here

不会描述所有的约束,但是会描述那些与计算 UI 对象的高度有关的约束。

  1. [ Label ] Labels 不能有固定的 height约束,在这种情况下,AutoLayout 不会调整标签的大小以适应文本,因此设置边缘约束是关键。(绿色箭头)
  2. 步骤1和步骤3非常容易遵循,但是这一步骤可能会被误解。与标签的情况一样,子视图不能设置 height约束。所有子视图都必须设置 top约束,忽略 bottom约束,这会使您认为在运行时会触发未满足的约束异常,但是如果为最后一个子视图设置 bottom约束,则不会触发此异常。如果不这样做,布局就会被破坏。< em > (红色箭头)

  3. [ Superview ] 按照您需要的方式设置所有约束,但是要特别注意 height约束。为它分配一个随机值,但是使它成为可选的,AutoLayout 将精确地设置高度以适应子视图。(蓝色箭头)

这非常完美,不需要调用任何额外的系统布局更新方法。