使用 AutoLayout 并确保父视图的边界在调整大小时适合子视图

Posted

技术标签:

【中文标题】使用 AutoLayout 并确保父视图的边界在调整大小时适合子视图【英文标题】:Using AutoLayout and ensuring bounds of parent view to fit subviews when resized 【发布时间】:2013-11-26 23:24:05 【问题描述】:

我真希望我能对自动布局有所了解。似乎每当我阅读关于事物应该如何工作的抽象描述时,它是有道理的,但每当我真正尝试并将其付诸实践时,它总是会引起巨大的头痛。因此,如果已经有答案但我找不到答案,我们深表歉意。

问题应该比较简单。我有一个容器视图,其中包含两个子视图,这里以丑陋的颜色显示以实现最大的可读性:):

底部(黑色)视图应保持其当前大小,并保持其与红色视图之间的间距,以及自身与黄色视图底部之间的间距。 我希望红色视图能够动态更改其高度,从而导致黑色视图相应地向上/向下移动,而黄色视图调整大小以适应红色+黑色视图。

对于黑色视图,我已将约束添加到:

将高度设置为 94 将前导和尾随空格固定到超级视图 将顶部空间设置为 51 处的红色视图。 将底部空间设置为 20 处的黄色视图。

我试图了解我需要添加哪些看似神秘的约束,以便当红色视图垂直调整大小时,黑色视图与红色视图保持当前距离并保持其大小,而外部容器视图相应地调整大小,使其包含红色视图 + 黑色视图 + 视图之间的垂直间距。

对于红色视图,我添加了约束以将顶部、左侧和右侧间距固定到超级视图,但没有运气解决垂直约束。目前我有一个约束固定高度=114,优先级为999,高度>=114,优先级为1000,认为这将确保视图的高度始终至少为114...

当我尝试手动设置红色视图的高度时,乐趣就开始了……我在视图上添加了一个按钮,当按下按钮时,我手动设置了红色视图的边界。 (红色视图默认高度为114):

CGRect bounds = self.redView.bounds;
bounds.size.height = 300;
self.redView.bounds = bounds;

当我运行它并按下按钮时,视图从这里开始:

到这里:

对我来说这毫无意义。为什么会导致:

红色视图的 Y 原点发生变化?特别是当有一个“必需的”约束告诉它距离黄色视图的顶部保持 20pts 时。 红色和黑色视图之间的间距被打破,即使对它们之间的间距的约束是“必需的”? 黄色视图的垂直尺寸不变。同样,尽管红+黑之间有间距,而且我尝试了几乎所有我能想到的压缩阻力和内容拥抱优先级的组合.....

我真的很想了解这一点,所以如果有人能解释需要哪些额外的约束/更改常量,我将不胜感激,但更重要的是为什么需要它们,因为对我来说,似乎根本不清楚布局系统给出了答案......

任何澄清都非常感谢。

提前致谢

(以上所有代码均在 ios 7 上运行并使用 Xcode 5.0.2 构建)。

【问题讨论】:

所以总结一下。除了红色视图之外,您的所有约束都是静态/依赖的?您可以尝试消除红色视图的高度约束吗?当你按下按钮时,你会这样做:heightOfRedviewConstraints.constant = 100;我真的很想帮助你,但我现在不在我的 xcode 上。呵呵 【参考方案1】:

你不需要任何花哨的约束来做你想做的事——没有不平等或弄乱优先级。除了对边的约束之外,红色视图应该有 20 到顶部,51 到黑色视图,高度约束为 114。黑色视图有 20 到底部,高度为 94。超级视图(黄色) 对顶部、左侧和右侧的约束应该为零——没有高度。您应该对红色视图的高度约束有一个 IBOutlet。当你想改变它的高度时,修改它的约束(不要设置框架):

- (IBAction)resizeYellowView:(id)sender 
    self.heightCon.constant = 300;

从黄色视图的顶部到底部的所有东西都以固定值链接在一起,所以当红色视图的高度发生变化时唯一可以改变的就是黄色视图的高度。

【讨论】:

谢谢!我不明白需要更改高度约束的常数,而不是更改高度本身。虽然我仍然不完全理解为什么通过边界设置高度不起作用,但在约束上设置常量确实可以解决问题 @JohnMartin,当您使用自动布局时,您根本不应该设置框架。一切都应该通过约束来完成。话虽如此,我无法解释为什么你会得到你所做的结果。 您在边界和框架上所做的事情稍后会在自动布局发生时被布局引擎覆盖。因此,当您处理自动布局时,不应使用它们。

以上是关于使用 AutoLayout 并确保父视图的边界在调整大小时适合子视图的主要内容,如果未能解决你的问题,请参考以下文章

UIViewController 容器视图内容扩展容器边界

如何使用 AutoLayout 使子视图确定父/兄弟视图大小?

如何使用 AutoLayout 根据父高度调整子视图高度而不添加/删除约束

SB中使用Autolayout设置到父视图的间距为0

添加到父视图时向 UITableView 添加 AutoLayout 约束

如果超出父视图边界,iOS7的子视图会被修剪[重复]