ios - 添加超过 4 个 subview 时自动布局无法满足约束

标签 ios autolayout

Auto Layout 正在做一些对我来说没有意义的事情,但希望对你们中的一个人来说:

我有一个 UIView containerView 和 5 个 UIView coverview1-coverview5。 我想在 containerView 中将这 5 个封面 View 并排放置:相同的宽度,相同的底部对齐方式,任何地方都没有间距,例如 |[ __ ][ __ ][ __ ][ __ ][ __ ]|

所以我在做:

[coverviewContainer addConstraints:[NSLayoutConstraint constraintsWithVisualFormat: 
  @"H:|[coverview1(>=0)][coverview2(==coverview1)][coverview3(==coverview1)][coverview4(==coverview1)][coverview5(==coverview1)]|" options:NSLayoutFormatAlignAllBottom metrics:nil views:viewsDictionary]];

我得到:

Unable to simultaneously satisfy constraints.
(
  "<NSLayoutConstraint:0x1d5ae4f0 ItemView:0x1d58f6f0.centerX == ItemView:0x1d580410.centerX>",
  "<NSLayoutConstraint:0x1d5ae470 ItemView:0x1d58f6f0.centerX == ItemView:0x1d59b480.centerX>",
  "<NSLayoutConstraint:0x1d5aed70 ItemView:0x1d580410.centerX == ItemView:0x1d59b480.centerX>"
)
Will attempt to recover by breaking constraint 
<NSLayoutConstraint:0x1d5ae470 ItemView:0x1d58f6f0.centerX == ItemView:0x1d59b480.centerX>

奇怪的是,如果我执行以下任一操作,我不会收到警告:

[coverviewContainer addConstraints:[NSLayoutConstraint constraintsWithVisualFormat: 
  @"H:|[coverview1(>=0)]|" options:NSLayoutFormatAlignAllBottom metrics:nil views:viewsDictionary]];
//or 
[coverviewContainer addConstraints:[NSLayoutConstraint constraintsWithVisualFormat: 
  @"H:|[coverview1(>=0)][coverview2(==coverview1)]|" options:NSLayoutFormatAlignAllBottom metrics:nil views:viewsDictionary]];
//or
[coverviewContainer addConstraints:[NSLayoutConstraint constraintsWithVisualFormat: 
  @"H:|[coverview1(>=0)][coverview2(==coverview1)][coverview3(==coverview1)]|" options:NSLayoutFormatAlignAllBottom metrics:nil views:viewsDictionary]];
//or
[coverviewContainer addConstraints:[NSLayoutConstraint constraintsWithVisualFormat: 
  @"H:|[coverview1(>=0)][coverview2(==coverview1)][coverview3(==coverview1)][coverview4(==coverview1)]|" options:NSLayoutFormatAlignAllBottom metrics:nil views:viewsDictionary]];
//or
[coverviewContainer addConstraints:[NSLayoutConstraint constraintsWithVisualFormat: 
  @"H:|[coverview1(>=0)][coverview2(==coverview1)][coverview3(==coverview1)][coverview5(==coverview1)]|" options:NSLayoutFormatAlignAllBottom metrics:nil views:viewsDictionary]];

(最后两个不一样,因为我用coverview5替换了coverview4)

为什么我最多只能添加 4 个 View ? 为什么添加第 5 个会导致 View centerX 对齐突然出现问题?

最佳答案

错误信息中有一个很好的提示:

Unable to simultaneously satisfy constraints.

因此,研究错误中显示的约束:

  "<NSLayoutConstraint:0x1d5ae4f0 ItemView:0x1d58f6f0.centerX == ItemView:0x1d580410.centerX>",
  "<NSLayoutConstraint:0x1d5ae470 ItemView:0x1d58f6f0.centerX == ItemView:0x1d59b480.centerX>",
  "<NSLayoutConstraint:0x1d5aed70 ItemView:0x1d580410.centerX == ItemView:0x1d59b480.centerX>"

我们可以看到有两个约束在 ItemView 实例 0x1d58f6f0 上指定相同的东西。第一个说它的 centerX 应该与 ItemView 实例 0x1d580410 centerX 相同。

第二个说它的 centerX 应该与 ItemView 实例 0x1d59b480 centerX 相同。

因此,我们有两个相互矛盾的约束条件。他们都试图告诉 ItemView 水平居中的位置,但他们都给出了不同的指令。想象一下,两个人同时对你大喊大叫,让你站在两个不同的地方。

Auto Layout runtime 会尽力处理这个问题。两个相互冲突的约束?忽略其中一个。在这种情况下,它会忽略或“破坏”约束 0x1d5ae470

您的其他约束条件如何?为什么他们使用四个 View 而不是五个?我们必须考虑到自动布局运行时将尝试根据您的意愿在容器 View 中布置 View 。有四个 View ,它可以做你想做的事。有五个 View ,它尝试做你想做的事,但失败了。这取决于设置的约束。如果 View 必须水平连续对齐,那么可以根据容器 View 的大小来完成吗?如果不是,您将需要水平宽度约束,以允许减小 ItemView 宽度,以便五个可以很好地组合在一起。

要考虑的另一件事是,您是否以编程方式创建了这些 View coverview1coverview5,或者它们是否在 Xib 中设置。两者都有问题。如果您以编程方式添加它们,则需要将 translatesAutoresizingMaskIntoConstraints 标志设置为 NO 以防止默认添加自动调整大小约束,这无疑会与您设置的约束发生冲突。

或者,如果您在 Xib 中创建了这些 View ,则需要以编程方式删除 Interface Builder 强加给您的任何现有约束。否则,这些可能会再次与您使用可视化格式语言以编程方式添加的内容发生冲突。

关于ios - 添加超过 4 个 subview 时自动布局无法满足约束,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15673522/

相关文章:

ios - 用于混合 V+H 的 AutoLayout 可视化语言

ios - 'CALayer 位置包含 NaN : [nan nan]' on UIScrollView

ios - 使用 anchor 的自动布局没有按照我的预期方式布置我的 View ?

ios - 将底线边框添加到 TextView - iOS

objective-c - 过滤 flickr 图片

iphone - iOS:如何创建和绘制(并保存)比屏幕大的图像?

ios - 应用程序中的所有元素都是像素化的

ios - UIImageView 拉伸(stretch)整个 UITableViewCell 的行高

ios - 具有动态变量的自动布局约束?

android - 移动应用程序的第三方 OAuth 注册和登录集成