无法同时满足约束 – 没有约束

我已经通过并删除了每一个用户的约束,但我仍然只是在我旋转设备后得到以下错误。 我绝对不知道为什么。 有没有人有任何想法?

2013-01-14 21:30:31.363 myApp[35869:c07] 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. (Note: If you're seeing NSAutoresizingMaskLayoutConstraints that you don't understand, refer to the documentation for the UIView property translatesAutoresizingMaskIntoConstraints) ( "<NSAutoresizingMaskLayoutConstraint:0x84543d0 h=--& v=--& V:[UIView:0xa330270(768)]>", "<NSLayoutConstraint:0xa338350 V:[UIView:0xa331260]-(-1)-| (Names: '|':UIView:0xa330270 )>", "<NSLayoutConstraint:0xa338390 V:|-(841)-[UIView:0xa331260] (Names: '|':UIView:0xa330270 )>" ) Will attempt to recover by breaking constraint <NSLayoutConstraint:0xa338350 V:[UIView:0xa331260]-(-1)-| (Names: '|':UIView:0xa330270 )> Break on objc_exception_throw to catch this in the debugger. The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKit/UIView.h> may also be helpful. 

我们一个一个来看看。

"<NSAutoresizingMaskLayoutConstraint:0x84543d0 h=--& v=--& V:[UIView:0xa330270(768)]>"

这是说视图0xa330270( A )必须是768点高。

"<NSLayoutConstraint:0xa338350 V:[UIView:0xa331260]-(-1)-| (Names: '|':UIView:0xa330270 )>"

这是说视图0xa331260( B )的底边必须是从A的底部-1,这是超视图的差距。

"<NSLayoutConstraint:0xa338390 V:|-(841)-[UIView:0xa331260] (Names: '|':UIView:0xa330270 )>"

这就是说, B的最高点必须是从它的超级观点A的顶端差841点。

这三件事情不可能都是真实的–A不能高768点,并且包含顶部边缘841个顶点和底部-1个顶点的子视图。 你在哪里定义了这些约束条件?

你还没有说过要实现什么样的布局,但是你看起来可能在超级视图上有一个自动调整的遮罩,当你旋转设备时,它可以防止它在高度上的变化。 据我所知,只有在以编程方式添加视图时才会出现自动调整约束,因为故事板或xib是全自动布局,或者不是。 除非你像添加一个自动布局视图(从一个笔尖加载?)到另一个非自动布局的笔尖视图?

感谢http://useYourLoaf.com这个完整的解决scheme:;

http://useyourloaf.com/blog/using-identifiers-to-debug-autolayout.html

我在WWDC 2015会议上发现了一个关于Auto Layout的快速提示,它有助于debugging带有约束的问题

如果你已经使用了自动布局,你将会熟悉Xcode在出错时logging的日志。 为了创build一个例子,我修改了我的Stack View示例代码,并为每个图像添加了一个约束,使它们具有240的固定宽度(不是我们将会看到的一个好主意)。

在这里输入图像说明

这适用于普通宽度的视图,例如iPad,但对于像iPhone这样的紧凑宽度视图来说太宽了。 运行时的控制台日志不好玩。 跳过样板文本,您将得到有问题的约束列表:

 "<NSLayoutConstraint:0x7fc1ab520360 H:[UIImageView:0x7fc1ab532650(240)]>", "<NSLayoutConstraint:0x7fc1ab536ef0 H:[UIImageView:0x7fc1ab537380(240)]>", "<NSLayoutConstraint:0x7fc1ab545cc0 UIView:0x7fc1ab53d870.trailingMargin == UIStackView:0x7fc1ab53dae0.trailing>", "<NSLayoutConstraint:0x7fc1ab545d10 UIStackView:0x7fc1ab53dae0.leading == UIView:0x7fc1ab53d870.leadingMargin>", "<NSLayoutConstraint:0x7fc1ab54e240 'UISV-alignment' UIStackView:0x7fc1ab53dc70.centerX == UIStackView:0x7fc1ab531a10.centerX>", "<NSLayoutConstraint:0x7fc1ab5167c0 'UISV-canvas-connection' UIStackView:0x7fc1ab531a10.leading == UIImageView:0x7fc1ab532650.leading>", "<NSLayoutConstraint:0x7fc1ab54ad80 'UISV-canvas-connection' H:[UIImageView:0x7fc1ab537380]-(0)-| (Names: '|':UIStackView:0x7fc1ab531a10 )>", "<NSLayoutConstraint:0x7fc1ab5397d0 'UISV-canvas-connection' UIStackView:0x7fc1ab53dae0.leading == _UILayoutSpacer:0x7fc1ab54c3c0'UISV-alignment-spanner'.leading>", "<NSLayoutConstraint:0x7fc1ab54a4a0 'UISV-canvas-connection' UIStackView:0x7fc1ab53dae0.centerX == UIStackView:0x7fc1ab53dc70.centerX>", "<NSLayoutConstraint:0x7fc1ab54b110 'UISV-spacing' H:[UIImageView:0x7fc1ab532650]-(16)-[UIImageView:0x7fc1ab537380]>", "<NSLayoutConstraint:0x7fc1ab548210 'UISV-spanning-boundary' _UILayoutSpacer:0x7fc1ab54c3c0'UISV-alignment-spanner'.leading <= UIStackView:0x7fc1ab531a10.leading>", "<NSLayoutConstraint:0x7fc1ab551690 'UIView-Encapsulated-Layout-Width' H:[UIView:0x7fc1ab53d870(375)]>" 

日志然后告诉你上面决定中断哪个约束:

 Will attempt to recover by breaking constraint <NSLayoutConstraint:0x7fc1ab536ef0 H:[UIImageView:0x7fc1ab537380(240)]> 

日志输出使用自动布局可视化格式语言,但很难从系统创build的约束中挑选我的约束。 堆栈视图的情况尤其如此,其devise旨在为您创build大部分约束条件。 在这个微不足道的例子中,我知道我刚刚添加的固定宽度的约束破坏了事物,但是很难从日志中看到越复杂的视图越难得到。

添加一个标识符到一个约束

如果你为每个约束添加一个标识符( NSLayoutConstraint自iOS 7以来有一个标识符属性),日志会更容易理解。 在界面生成器中find约束并在属性检查器中添加标识符(我使用$作为前缀/后缀,使它们在日志中脱颖而出):

在这里输入图像说明

2015年8月18日更新:正如在注释中指出的那样,标识符只能在从Xcode 7开始的Interface Builder中编辑。它在Xcode 6.4中不可见。

如果在代码中添加约束:

 constraint.identifier = "$HeartImageFixedWidth$" 

如果您使用使用约束数组的视觉格式语言,则更为复杂。 例如,考虑Swift代码片段为心脏图像视图创build一个固定的宽度约束:

 let heartWidth = NSLayoutConstraint.constraintsWithVisualFormat("[heart(240)]", options:[], metrics:nil, views:viewsDictionary) 

因为heartWidth是一个[NSLayoutConstraint]types的数组,所以标识符是一个更多的工作:

 for constraint in heartWidth { constraint.identifier = "$HeartImageFixedWidth$" } heartImage.addConstraints(heartWidth) 

通过为我的约束设置标识,现在在日志文件中查找它们变得更加容易(请参阅前四行):

 "<NSLayoutConstraint:0x7f92a305aeb0 '$ContainerStackViewLeading$' UIStackView:0x7f92a3053220.leading == UIView:0x7f92a3052fb0.leadingMargin + 32>", "<NSLayoutConstraint:0x7f92a305b340 '$ContainerStackViewTrailing$' UIView:0x7f92a3052fb0.trailingMargin == UIStackView:0x7f92a3053220.trailing + 32>", "<NSLayoutConstraint:0x7f92a301cf20 '$HeartImageFixedWidth$' H:[UIImageView:0x7f92a3047ef0(240)]>", "<NSLayoutConstraint:0x7f92a3009be0 '$StarImageFixedWidth$' H:[UIImageView:0x7f92a304d190(240)]>", "<NSLayoutConstraint:0x7f92a3060cc0 'UISV-alignment' UIStackView:0x7f92a30533b0.centerX == UIStackView:0x7f92a30472b0.centerX>", "<NSLayoutConstraint:0x7f92a301c590 'UISV-canvas-connection' UIStackView:0x7f92a30472b0.leading == UIImageView:0x7f92a3047ef0.leading>", "<NSLayoutConstraint:0x7f92a305f680 'UISV-canvas-connection' H:[UIImageView:0x7f92a304d190]-(0)-| (Names: '|':UIStackView:0x7f92a30472b0 )>", "<NSLayoutConstraint:0x7f92a3064190 'UISV-canvas-connection' UIStackView:0x7f92a3053220.leading == _UILayoutSpacer:0x7f92a30608a0'UISV-alignment-spanner'.leading>", "<NSLayoutConstraint:0x7f92a30415d0 'UISV-canvas-connection' UIStackView:0x7f92a3053220.centerX == UIStackView:0x7f92a30533b0.centerX>", "<NSLayoutConstraint:0x7f92a305fa10 'UISV-spacing' H:[UIImageView:0x7f92a3047ef0]-(16)-[UIImageView:0x7f92a304d190]>", "<NSLayoutConstraint:0x7f92a30508c0 'UISV-spanning-boundary' _UILayoutSpacer:0x7f92a30608a0'UISV-alignment-spanner'.leading <= UIStackView:0x7f92a30472b0.leading>", "<NSLayoutConstraint:0x7f92a3063240 'UIView-Encapsulated-Layout-Width' H:[UIView:0x7f92a3052fb0(375)]>" 

这也更清楚地表明系统select打破哪些限制:

 Will attempt to recover by breaking constraint <NSLayoutConstraint:0x7f92a3009be0 '$StarImageFixedWidth$' H:[UIImageView:0x7f92a304d190(240)]> 

为约束添加标识符并非毫不费力,但是在下一次您必须对复杂布局的debugging日志进行sorting时,才能付诸实施。

进一步阅读

  • WWDC 2015 Session 219自动布局之谜,第2部分

我想这不是一个常见的错误,但是我以通俗的方式解决了这个问题。 我收到了像上面那样的神秘消息。 为了理解它,我创build了虚拟视图类,并将其附加到故事板中的视图中。 例如,如果我有一个UIView,我创build了一个名为AddressView的类,并将它附加到故事板中的这个视图。 它有点耗时,但它为我工作。 之后,而不是对象ids,我得到了类名,这帮助我零容易导致问题的意见。 我的错误消息现在阅读,

 2013-07-02 04:16:20.434 Myproject [2908:c07] 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. (Note: If you're seeing NSAutoresizingMaskLayoutConstraints that you don't understand, refer to the documentation for the UIView property translatesAutoresizingMaskIntoConstraints) ( "<NSLayoutConstraint:0x9edeae0 V:|-(0)-[AddressView:0x143ee020] (Names: '|':MainView:0x129eb6a0 )>", "<NSAutoresizingMaskLayoutConstraint:0x11e998c0 h=--& v=--& V:[MainView:0x129eb6a0(704)]>", "<NSLayoutConstraint:0x156720b0 V:[AddressView:0x143ee020]-(896)-| (Names: '|':MainView:0x129eb6a0 )>" ) 

在这里你可以看到,我的视图MainView和Address视图的名字是造成这个问题的原因。

为了解决这个问题,我只是移动我的子视图(在这种情况下地址视图),并重新定位它。 我认为这个问题是由于我在Xcode 4.5和旧技能中使用了新的Automatic Layour,或者是手动定位视图。

无论如何,不​​知道这是否比勤奋更幸运,但是这可能是一种不同的debugging方式。 也许这有助于某人!

YourConstraintView.translatesAutoresizingMaskIntoConstraints = NO;

是为我做的。

我已经解决了这个问题,从xib文件中删除所有translatesAutoresizingMaskIntoConstraints属性(打开xib作为源代码)。

一个音符。 如果您使用个人热点连接进行testing,并且热点状态栏位于顶部,则会在日志中看到此错误。 它抛弃了限制。

希望这可以帮助一个人..让我疯狂。

它值得了解基础知识,并了解Apple / Xcode试图通过日志告诉你什么

 H = Horizontal constraint(for leading and Trailing) V = Vertical constraint(top and bottom edge) h = height w = width TopEdge -> V:|-(points)-[VIEW:memoryAddress] BottomEdge -> V:[VIEW:memoryAddress]-(points)-| Leading -> H:|-(points)-[VIEW:memoryAddress] Trailing -> H:[VIEW:memoryAddress] -(points)-| height -> h= --& v=--& V:[VIEW:memoryAddress((points)] width -> VIEW:memoryAddress.width == points between -> H:[VIEW 1]-(51)-[VIEW 2] 

一旦你明白这一点,阅读你的具体错误是很容易的