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


83

我不能为上帝的爱而努力,而这正是调整规模的Superview的用处。

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

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

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

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

在那里,我如何使用这些SizeToFitVS sizeThatFits:(CGSize)VS UIView systemLayoutSizeFittingSize:,无论是传球UILayoutFittingCompressedSize还是UILayoutFittingExpandedSize。我在这里已经阅读了很多技巧,但最终没有结果。

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

我正在挠..帮助


1
嘿,如果我可以看一下,您可以将代码发布在pastebin上吗?我也遇到类似的问题。已经一周或更长时间了。
esh

Answers:


104

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

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

  2. 确保每个标签的边缘都牢固地连接在一起(具有必需的优先级约束),并且彼此之间以及它们的视图之间均紧密连接。您想确保如果您想象其中一个标签的大小在增加,这将迫使其他标签为其腾出空间,最重要的是也迫使超级视图也扩大。

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

而已。您无需调用sizeToFitsystemLayoutSizeFittingSize:使其正常工作,只需加载视图并设置文本即可。系统布局引擎将为您进行计算以解决您的约束。(如果有的话,您可能需要调用setNeedsLayout父视图...但这不是必需的。)


谢谢smileyborg。自从我进入一个项目的中期以来,我就迟迟未做出答复,却没有完全理解您的想法。现在,我有机会在程序上,特别是在约束上进行更多工作constraintsWithVisualFormat,我完全
理解

我同意该解决方案,但不适用于我,请检查stackoverflow.com/questions/34635838/…–
Omer

这个答案是神奇的。我要付出的努力要少得多,以使视图看起来不错。
克里斯,

1
应该提到的是,translatesAutoresizingMaskIntoConstraints = NO如果您使用的是xib ,则应进行设置。
KudoCC

translationsAutoresizingMaskIntoConstraints = NO是我的情况的答案。但是现在,容器视图丢失的帧及其原点始终为(0,0),我无法将其放到希望的位置。stackoverflow.com/questions/45548372/…–
karim

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


12
-UIViewShowAlignmentRects YES-大提示!
拉方索2015年

2
在这种情况下,容器只需要使其高度适应标签即可。如果容器应适应多于一个视图的高度之和怎么办?
da Rocha Pires

7

在iOS 9中引入了“堆栈视图”,这大大简化了操作。在视图内部使用堆栈视图来包含所有调整大小的内容,然后只需调用

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

更改内容后。然后,您可以通过致电获得新的尺寸

view.systemLayoutSizeFittingSize(UILayoutFittingCompressedSize)

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


2
我正在使用StackView并动态添加视图,这些视图的大小没有调整。@ JacobRuth
Mansuu...。

6

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

在此处输入图片说明

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

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

  3. [Superview]根据需要设置所有约束,但要特别注意 height约束。给它分配一个随机值,但将其设置为可选值,则AutoLayout会将高度设置为恰好适合子视图。(蓝色箭头)

这可以完美地工作,无需调用任何其他系统布局更新方法。


如何使高度可选。.我是iOS的新手,所以无法弄清楚。谢谢
Faisal Naseer
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.