尺寸类自动布局:为错误的尺寸类激活约束

4
当我设置了一个由Size Classes定制的自动布局约束,这个约束被安装在某些Size Class(es)中,而在其他Size Class(es)中没有安装时,我在运行时会收到这个不可满足的约束错误消息,但是在Interface Builder上的结果符合预期,没有错误/警告。

enter image description here

enter image description here

我正在测试什么

为了演示不可满足约束条件如何意外发生的简单示例,我希望星形图像具有固定的高度,但根据大小类别自定义宽度。如您在图像中所看到的,我希望它在常规宽度下非常大。

因为紧凑宽度下未安装宽度约束条件,所以它基于星形图像的内在内容获取图像大小。(来源:此星形图像来自Use Your Loaf

问题

当我在模拟器上运行iPhone 8 Plus(iOS 11.1与Xcode 9.1)将设备从横向旋转至纵向时,我会收到以下错误:

Unable to simultaneously satisfy constraints.
Probably at least one of the constraints in the following list is one you don't want. 
Try this: 
    (1) look at each constraint and try to figure out which you don't expect; 
    (2) find the code that added the unwanted constraint or constraints and fix it.

....


Will attempt to recover by breaking constraint 
<NSLayoutConstraint:0x6040002839d0 UIImageView:0x7fe177d0b940.width == 480   (active)>

显然,即使我的视图改变为紧凑宽度,我指定不安装约束时,这个宽度约束仍然存在。为什么会这样?在Storyboard中使用installed是基于不同的Size Class自定义自动布局约束的正确方式吗?但我没有看到其他实现方式。

我尝试通过编写代码创建宽度约束,并从traitCollectionDidChange内部设置.isActive,但仍然出现了相同的错误。

当我测试Mysteries of Auto Layout WWDC talk的示例代码时,我没有遇到这样的错误,该示例代码与我一样通过traitCollectionDidChange来启用/禁用约束。

更新

我在GitHub上添加了自己的代码。

2个回答

4

您可以通过将宽度约束的优先级降低到999来消除此错误。

我认为这个警告与自动布局引擎自动添加的UIView-Encapsulated-Layout-Width约束有关。关于这种类型的约束有很多问题,但我没有找到任何好的答案,说明它是什么以及它的作用是什么。我找到的最好的答案是这个thread

<NSLayoutConstraint:0x60400008d110 'UIView-Encapsulated-Layout-Width' UIView:0x7ff1e5f08d20.width == 414   (active)>

如果您在视图层次结构调试器中预览布局,您会发现所有约束都按预期在两个方向上设置好了。

portrait configuration preview Landscape configuration preview


1
谢谢您的回答。我一开始也注意到了这个限制,我认为仅仅通过这种方式来消除错误可能会隐藏实际存在的问题,而我还不确定是什么问题。因此,我更希望得到一个真正解释发生了什么的答案。 - HuaTham

1
我曾遇到一个类似的问题,尝试在两个有冲突的约束之间进行切换。我的问题是,在另一个约束已经激活时,我仍然激活了冲突的约束,从而导致出现警告。请先停用存在冲突的约束,再启用新的约束,这样就可以消除警告。
if isWide {
    wideConstraint.isActive = false
    narrowConstraint.isActive = true
else {
    narrowConstraint.isActive = false
    wideConstraint.isActive = true
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接