使用autolayout动态更改子视图后调整superview的大小

时间:2013-10-03 22:10:12

标签: ios objective-c uiview autolayout autoresize

我不能为上帝的爱而担任这个调整大小的超级视图的悬念。

我有UIView *superviewUILabels。 2作为另外2个人的标题。

所有4个内容都来自数据库。

SizeToFit vs SizeThatFits:(CGSize) vs UIView systemLayoutSizeFittingSize:,传递UILayoutFittingCompressedSizeUILayoutFittingExpandedSize

我以编程方式使用autolayout并将superview高度设置为等于或大于虚拟数字。

我在哪里以及如何使用这些SizeToFit vs sizeThatFits:(CGSize) vs UIView systemLayoutSizeFittingSize:,传递UILayoutFittingCompressedSizeUILayoutFittingExpandedSize。我已经在堆栈上阅读了很多提示,但结果却没有。

我是否需要在某处特定的情况下重新计算superview的约束。 Maby在其控制器类中将高度设置为'@ property`并删除并读取它? Atm我试图将所有东西都放在一起然后放一些。我仍然得到相同大小的最终结果,虚拟高度和文字漂浮在外面。甚至在子视图上设置clipsToBound后。

我正在抓我的头发......帮助

4 个答案:

答案 0 :(得分:102)

如果您正在使用自动布局,请执行以下操作:

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

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

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

  4. 就是这样。您无需致电sizeToFitsystemLayoutSizeFittingSize:即可使其正常工作,只需加载您的观点并设置文字即可。系统布局引擎将为您进行计算以解决您的约束。 (如果有的话,您可能需要在超级视图上调用setNeedsLayout ...但这不是必需的。)

答案 1 :(得分:24)

使用容器视图

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

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

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

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

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

黄色对齐矩形

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

UILabel that is multi-line

答案 2 :(得分:5)

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

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

更改内容后。然后你可以通过调用

来获得新的大小
view.systemLayoutSizeFittingSize(UILayoutFittingCompressedSize)

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

答案 3 :(得分:3)

这几乎遵循@smileyborg的答案并附带一个具体的例子。

enter image description here

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

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

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

  4. 这非常有效,无需调用任何其他系统布局更新方法。