84

我不能为上帝的爱这个调整大小的超级视图的窍门。

我有一个UIView *superview 4 UILabels。2 用作其他 2 的标题。

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

SizeToFitvs SizeThatFits:(CGSize)vs UIView systemLayoutSizeFittingSize:,通过UILayoutFittingCompressedSizeUILayoutFittingExpandedSize

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

我在哪里以及如何使用这些SizeToFitvs sizeThatFits:(CGSize)vs UIView systemLayoutSizeFittingSize:,通过UILayoutFittingCompressedSizeor 或UILayoutFittingExpandedSize. 我在堆栈上阅读了很多技巧,但最终一无所获。

我是否需要在特定的地方重新计算超级视图的约束。可能在其控制器类中将高度设置为“@property”并删除并读取它?Atm 我试图把所有东西都放在任何地方,然后再放一些。我仍然得到相同大小的最终结果,虚拟高度和文本漂浮在外面。即使在子视图上设置 clipsToBound 之后。

我正在抓挠我的头发……救命

4

4 回答 4

107

如果您使用的是自动布局,则需要执行以下操作:

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

  2. 确保每个标签的边缘都严格连接(具有必需的优先级约束)到彼此的边缘及其父视图。您要确保如果您想象其中一个标签的大小增加,这将迫使其他标签为其腾出空间,最重要的是迫使超级视图也扩大。

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

而已。你不需要打电话sizeToFitsystemLayoutSizeFittingSize:让它工作,只需加载你的视图并设置文本就可以了。系统布局引擎将为您进行计算以解决您的约束。(如果有的话,您可能需要调用setNeedsLayout超级视图......但这不应该是必需的。)

于 2013-10-05T06:05:56.290 回答
24

使用容器视图

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

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

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

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

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

黄色对齐矩形

如果您希望黄色对齐矩形添加-UIViewShowAlignmentRects YES到您的方案的运行参数列表中。

多行的 UILabel

于 2014-01-28T13:51:25.577 回答
8

这几乎遵循@smileyborg 的回答,并附有一个具体的例子。

在此处输入图像描述

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

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

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

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

于 2017-09-21T23:36:28.837 回答
7

随着 iOS 9 中堆栈视图的引入,这变得非常容易。在视图中使用堆栈视图来包含所有调整大小的内容,然后只需调用

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

更改内容后。然后你可以通过调用获得你的新尺寸

view.systemLayoutSizeFittingSize(UILayoutFittingCompressedSize)

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

于 2016-08-30T01:11:38.240 回答