ios 使用自动布局动态更改子视图后调整超级视图的大小
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/19170053/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
resize superview after subviews change dynamically using autolayout
提问by Pedroinpeace
I cant for the love of god the the hang of this resizing superview.
我不能为上帝的爱这个调整大小的超级视图的窍门。
I have a UIView *superview
with 4 UILabels
. 2 function as header for the 2 others.
我有一个UIView *superview
4 UILabels
。2 用作其他 2 个的标题。
The content in all 4 are dynamic coming from database.
所有 4 个中的内容都是来自数据库的动态内容。
SizeToFit
vs SizeThatFits:(CGSize)
vs UIView systemLayoutSizeFittingSize:
, passing either UILayoutFittingCompressedSize
or UILayoutFittingExpandedSize
.
SizeToFit
vs SizeThatFits:(CGSize)
vs UIView systemLayoutSizeFittingSize:
,通过UILayoutFittingCompressedSize
或UILayoutFittingExpandedSize
。
I use autolayout programatically and have set the superview height to be equal or greater to a dummy number.
我以编程方式使用自动布局并将超级视图高度设置为等于或大于虚拟数字。
where and how do I use these SizeToFit
vs sizeThatFits:(CGSize)
vs UIView systemLayoutSizeFittingSize:
, passing either UILayoutFittingCompressedSize
or UILayoutFittingExpandedSize
. I have read a lot of tips here on stack but ended up with nothing.
我在哪里以及如何使用这些SizeToFit
vs sizeThatFits:(CGSize)
vs UIView systemLayoutSizeFittingSize:
,通过UILayoutFittingCompressedSize
或UILayoutFittingExpandedSize
. 我在这里阅读了很多关于堆栈的提示,但最终什么也没有。
DO I need to recalculate the constraints for the superview somewhere specific. Maby setting the height to be ′@property` in its controller class and remove and readd it? Atm I have tried to put everything everywhere and then some. Still I get the same size end result with the dummy height and text floating outside. Even after setting clipsToBound on subview.
我是否需要在特定的地方重新计算超级视图的约束。Maby 在其控制器类中将高度设置为“@property”并删除并读取它?Atm 我试图把所有的东西都放在任何地方,然后再放一些。我仍然得到相同大小的最终结果,虚拟高度和文本漂浮在外面。即使在子视图上设置 clipsToBound 之后。
I am scratching my hair of.. help
我正在抓我的头发..帮助
回答by smileyborg
If you're using Auto Layout, here's what you need to do:
如果您使用自动布局,您需要执行以下操作:
Make sure you aren't adding fixed width and/or height constraints to any of your subviews (depending on which dimension(s) you want to dynamically size). The idea is to let the intrinsic content size of each subview determine the subview's height.
UILabel
s come with 4 automatic implicit constraints which will (with less than Required priority) attempt to keep the label's frame at the exact size required to fit all the text inside.Make sure that the edges of each label are connected rigidly (with Required priority constraints) to the edges of each other and their superview. You want to make sure that if you imagine one of the labels growing in size, this would force the other labels to make room for it and most importantly force the superview to expand as well.
Only add constraints to the superview to set its position, not size (at least, not for the dimension(s) you want it to size dynamically). Remember that if you set the internal constraints up correctly, its size will be determined by the sizes of all the subviews, since its edges are connected to theirs in some fashion.
确保您没有向任何子视图添加固定宽度和/或高度约束(取决于您想要动态调整大小的维度)。这个想法是让每个子视图的内在内容大小决定子视图的高度。
UILabel
s 带有 4 个自动隐式约束,它们将(优先级低于 Required )尝试将标签的框架保持在适合其中所有文本所需的确切大小。确保每个标签的边缘与彼此的边缘及其父视图严格连接(具有必需的优先级约束)。您想确保如果您想象其中一个标签的大小不断增长,这将迫使其他标签为其腾出空间,最重要的是,也将迫使超级视图扩展。
仅向超级视图添加约束以设置其位置,而不是大小(至少,不是您希望它动态调整大小的维度)。请记住,如果您正确设置了内部约束,其大小将由所有子视图的大小决定,因为它的边缘以某种方式连接到它们的边缘。
That's it. You don't need to call sizeToFit
or systemLayoutSizeFittingSize:
to get this to work, just load your views and set the text and that should be it. The system layout engine will do the calculations for you to solve your constraints. (If anything, you might need to call setNeedsLayout
on the superview...but this shouldn't be required.)
就是这样。你不需要调用sizeToFit
或systemLayoutSizeFittingSize:
让它工作,只需加载你的视图并设置文本就可以了。系统布局引擎将为您进行计算以解决您的约束。(如果有的话,您可能需要调用setNeedsLayout
超级视图......但这不应该是必需的。)
回答by Cameron Lowell Palmer
Use container views
使用容器视图
In the following example I have a 30x30 image, and the UILabel
is smaller than the containing view with the placeholder text. I needed the containing view to be at least as big as the image, but it needed to grow to contain multi-line text.
在下面的示例中,我有一个 30x30 的图像,并且UILabel
小于带有占位符文本的包含视图。我需要包含视图至少与图像一样大,但它需要增长以包含多行文本。
In visual format the inner container looks like this:
在视觉格式中,内部容器如下所示:
H:|-(15.0)-[image(30.0)]-(15.0)-[label]-(15.0)-|
V:|[image(30.0)]|
V:|[label(>=30.0)]|
Then, set the containing view to match the height of the label. Now the containing view will ride the size of the label.
然后,设置包含视图以匹配标签的高度。现在包含视图将乘坐标签的大小。
As @smileyborg pointed out in his answer, connecting the content rigidly to the superview informs the layout engine that the simple container view should cause it to grow.
正如@smileyborg 在他的回答中指出的那样,将内容严格地连接到超级视图会通知布局引擎简单的容器视图应该使其增长。
Yellow alignment rectangles
黄色对齐矩形
If you want the yellow alignment rectangles add -UIViewShowAlignmentRects YES
in your scheme's list of run arguments.
如果您希望黄色对齐矩形添加-UIViewShowAlignmentRects YES
到您的方案的运行参数列表中。
回答by Jacob Ruth
This was made dramatically easier with the introduction of Stack Views in iOS 9. Use a stack view inside your view to contain all your content that resizes, and then simply call
随着 iOS 9 中堆栈视图的引入,这变得非常容易。在视图中使用堆栈视图来包含所有调整大小的内容,然后只需调用
view.setNeedsUpdateConstraints()
view.updateConstraintsIfNeeded()
view.setNeedsLayout()
view.layoutIfNeeded()
after changing your content. Then you can get your new size by calling
更改内容后。然后您可以通过致电获取新尺寸
view.systemLayoutSizeFittingSize(UILayoutFittingCompressedSize)
if you ever need to calculate the exact size required for a view.
如果您需要计算视图所需的确切大小。
回答by tesla
This almost follows @smileyborg answer and comes with a concrete example.
这几乎遵循@smileyborg 的回答,并附有一个具体的例子。
Won't describe all constraints, but those related to the calculation of the height of UI objects.
不会描述所有约束,但会描述与 UI 对象高度计算相关的约束。
- [Label]Labels must not have a fixed
height
constraint, in this case, AutoLayout won't resize labels to fit the text, so setting edge constraints is the key. (green arrows) [Subview]Steps 1 and 3 are very easy to follow, but this step can be misunderstood. As in the case with labels, subviews must not have
height
constraint set. All subviews must havetop
constraint set, ignoringbottom
constraint, which can make you think will trigger unsatisfied constraint exception at runtime, but it won't if you setbottom
constraint for the last subview. Missing to do so will blow the layout. (red arrows)[Superview]Set all constraints the way you need, but pay big attention to the
height
constraint. Assign it a random value, but make it optional, AutoLayout will set the height exactly to fit the subviews. (blue arrows)
- [标签]标签不能有固定
height
约束,这种情况下,AutoLayout 不会调整标签大小以适应文本,所以设置边缘约束是关键。(绿色箭头) [子视图]步骤 1 和 3 很容易遵循,但是这一步可能会被误解。与标签的情况一样,子视图不能
height
设置约束。所有子视图都必须top
设置约束,忽略bottom
约束,这会让您认为在运行时会触发未满足的约束异常,但如果您bottom
为最后一个子视图设置约束则不会。不这样做会破坏布局。(红色箭头)[Superview]按照您需要的方式设置所有约束,但要非常注意
height
约束。为其分配一个随机值,但使其可选,AutoLayout 将设置高度以完全适合子视图。(蓝色箭头)
This works perfectly, there is no need to call any additional system-layout update methods.
这非常有效,无需调用任何额外的系统布局更新方法。