0

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

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

所以我在做:

[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]];

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

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

4

1 回答 1

2

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

无法同时满足约束。

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

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

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

第二个说它centerX应该与ItemViewinstance相同0x1d59b480 centerX

因此,我们有两个相互矛盾的约束。他们都试图告诉在ItemView哪里放置它的水平中心,并且他们都给出了不同的指示。想想两个人同时对你大喊大叫,告诉你站在两个不同的地方。

自动布局运行时最好处理这个问题。两个相互冲突的约束?忽略其中之一。在这种情况下,它会忽略或“打破”约束0x1d5ae470

你的其他有效限制呢?为什么他们使用四个视图而不是五个视图?我们必须考虑到 Auto Layout 运行时会尝试根据您的意愿在容器视图中布局视图。有四个视图,它可以做你想做的事。有五个视图,它试图做你想做的事,但失败了。这取决于设置的约束。如果视图必须水平连续对齐,那么在给定容器视图大小的情况下可以这样做吗?如果没有,您将需要水平宽度约束,允许ItemView宽度减小,以便五个可以很好地组合在一起。

要考虑的另一件事是您是否coverview1通过coverview5编程方式创建了这些视图,或者它们是否在 Xib 中设置。两者都有问题。如果您以编程方式添加它们,则需要设置translatesAutoresizingMaskIntoConstraints标志以NO防止默认情况下添加自动调整大小约束,并且无疑会与您设置的约束冲突。

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

于 2013-07-30T11:10:44.827 回答