大小等级' d自动布局:针对错误的大小类

时间:2017-11-08 13:58:27

标签: ios swift xcode autolayout size-classes

当我设置由大小类自定义的自动布局约束时,约束安装在某些大小类中,而不安装在其他大小类中,我在运行时获得此不满足约束错误消息,但结果如预期在Interface Builder上没有错误/警告。

enter image description here

enter image description here

我在测试什么

对于这个简化的例子,为了演示不可满足的约束如何意外发生,我希望星形图像具有固定的高度,但是基于尺寸类的自定义宽度。正如您在图像中看到的那样,我希望它对于常规宽度来说相当大。

由于未为Compact Width安装宽度约束,因此它会根据星形图像的内在内容获取图像大小。 (信用:此明星来自Use Your Loaf

问题

当我在运行iPhone 8 Plus的模拟器(带有Xcode 9.1的iOS 11.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)>

显然,即使我的视图更改为Compact Width,这个宽度约束仍然存在,我指定要在其中安装约束NOT。为什么是这样?是否使用installed正确的方法来根据不同的大小类自定义自动布局约束?但我在Storyboard中没有看到任何其他方法来实现它。

我尝试以编程方式创建宽度约束,然后在.isActive内设置traitCollectionDidChange,我仍然遇到同样的错误。

Mysteries of Auto Layout WWDC talk测试示例代码时,我没有收到此类错误,这正在通过traitCollectionDidChange停用/激活约束,就像我一样。

更新

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

2 个答案:

答案 0 :(得分:2)

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

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

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

如果您将在视图层次结构调试器中查看布局预览,您将看到所有约束都按预期在两个方向中设置。

portrait configuration preview Landscape configuration preview

答案 1 :(得分:1)

我有一个类似的问题,我试图在两个相互矛盾的约束之间切换。我的问题是我正在激活冲突的约束,而另一个也是活跃的,我会得到这个警告。

首先尝试停用冲突的活动约束,然后激活新约束。这将消除警告。

if isWide {
    wideConstraint.isActive = false
    narrowConstraint.isActive = true
else {
    narrowConstraint.isActive = false
    wideConstraint.isActive = true
}