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

时间:2013-01-14 21:35:28

标签: ios ipad autoresizingmask nslayoutconstraint

我已经完成并删除了每个用户约束,但在旋转设备后,我仍然遇到以下错误 ONLY 。我完全不知道为什么。有没有人有任何想法?

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.

11 个答案:

答案 0 :(得分:94)

让我们逐一看看这些。

"<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 的最高优势必须是超级视图顶部841点的差距, A

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

您还没有说过要尝试实现的布局,但看起来您可能在superview上有一个自动调整遮罩,可以防止它在旋转设备时高度变化。据我所知,只有在您以编程方式添加视图时才会出现自动调整约束,因为故事板或xib要么是全自动布局的,要么是全自动布局。除非您正在做一些事情,例如将自动布局视图(从笔尖加载?)添加到非自动布局笔尖的另一个视图中?

答案 1 :(得分:13)

感谢http://useYourLoaf.com这个完整的解决方案:

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

我发现了一个快速提示,我在WWDC 2015的Auto Layout会话中被隐藏起来,可以帮助调试约束问题

如果您使用过自动布局,那么当您出错时,您将熟悉Xcode吐出的日志。为了创建一个示例,我修改了my Stack View sample code并为每个图像添加了一个约束,使它们具有240的固定宽度(不是我们将看到的好主意)。

enter image description here

适用于常规宽度视图,例如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)]>

日志输出使用自动布局可视格式语言,但很难从系统创建的约束中挑选出约束。对于堆栈视图尤其如此,这些堆栈视图旨在为您创建大多数约束。在这个简单的例子中,我知道我刚刚添加的固定宽度约束破坏了东西,但很难从日志中看到它,视图越复杂越难。

将标识符添加到约束

如果为每个约束添加标识符,则日志会更容易理解(NSLayoutConstraint自iOS 7以来具有标识符属性)。在Interface Builder中找到约束并在Attributes检查器中添加标识符(我使用$作为前缀/后缀使它们在日志中脱颖而出):

enter image description here

2015年8月18日更新:正如评论中所指出的,标识符只能在Interface Builder中以Xcode 7开头编辑。它在Xcode 6.4中不可见。

如果在代码中添加约束:

constraint.identifier = "$HeartImageFixedWidth$"

如果您使用使用约束数组的可视化格式语言,则会更棘手。例如,考虑使用Swift代码片段为心脏图像视图创建固定宽度约束:

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

由于heartWidth是一个类型为[NSLayoutConstraint]的数组,因此设置标识符的工作要多一些:

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)]>"

系统选择破坏的哪些约束也更加清晰:

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

向约束添加标识符并非毫不费力,但是下次您需要对复杂布局的调试日志进行排序时,它可以获得回报。

进一步阅读

答案 2 :(得分:9)

我想这不是一个常见的错误,但我以外行的方式解决了一些问题。我收到了如上所述的神秘信息。为了理解它,我创建了虚拟视图类并将其附加到我的故事板中的视图。例如,如果我有一个UIView,我创建了一个名为AddressView的类,并将其附加到故事板中的此视图。它有点耗时,但它对我有用。在那之后,我没有使用object-id,而是获得了类名,这有助于我轻松地查看导致问题的视图。我现在看到我的错误消息,

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和地址视图导致了这个问题。

要解决它,我只是移动了我的子视图(在本例中是地址视图)并重新定位它。我认为这个问题始于我在Xcode 4.5中使用新的自动Layour和旧技能,或手动定位视图。

无论如何,不​​确定它是否比勤奋更幸运,但不过这可能是一种不同的调试方式。也许这有助于某人!

答案 3 :(得分:6)

值得了解基础知识,并了解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] 

一旦理解了这一点,就可以轻松阅读特定错误

答案 4 :(得分:4)

YourConstraintView.translatesAutoresizingMaskIntoConstraints = NO;

为我做了。

答案 5 :(得分:3)

我已修复此问题,即从xib文件中删除所有translatesAutoresizingMaskIntoConstraints属性(打开xib作为源代码)。

答案 6 :(得分:2)

一个注意事项。如果您使用个人热点连接进行测试,并且热点状态栏位于顶部,则会在日志中出现此错误。它抛弃了约束。

希望这有助于某人......让我疯狂。

答案 7 :(得分:0)

对我来说,当我给tableView.estimatedRowHeight = UITableViewAutomaticDimension

时,这个错误就出现了

这应该是tableView.estimatedRowHeight = "Some hardcoded value"

答案 8 :(得分:0)

我遇到了这个问题,花了我两天的时间来弄清楚问题的根源....

如果您在代码中以编程方式打开故事板,请确保执行此操作:

UIStoryboard *story = [UIStoryboard storyboardWithName:@"MovieMaker" bundle:nil];
    UIViewController *vc = [story instantiateInitialViewController];
    //this causes layout to break [self presentViewController:vc animated:YES completion:nil];
    [self showViewController:vc sender:nil];

我正在使用注释行(使用presentViewController)并且定向错误发生了抛出不是我约束的约束冲突...更改为showViewController所有约束冲突都消失了,取向工作......(I不知道为什么它适用于节目而不存在...仍然认为它是...... ALIENS ......)

答案 9 :(得分:0)

在XCode 9.4中也遇到了在调试控制台中生成的消息“无法同时满足矛盾”的问题。
在我在iPad模拟器上的特定实例中,该消息将生成:
1)仅在将焦点放在特定的UITextField上时。
2)即使移除了所有视图约束,
2)即使所有视图都有矛盾,“重置为建议的约束”。

但是,当打开软件键盘以使其显示时,将不会生成该消息。 因此,在这个问题上,我应该花多少时间,在我的实例中,只有在关闭软件键盘时才会生成该时间。

答案 10 :(得分:0)

当在 uitableviewCell 中记录像上面这样的日志时,这一行解决了我的问题

func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
    return UITableView.automaticDimension > CellHeight.rowHeight44 ? UITableView.automaticDimension : CellHeight.rowHeight44
}