如何找出与 NSLayoutConstraints 的确切冲突?

How to find out the exact conflicts with NSLayoutConstraints?

我正在尝试将我的 40x40 徽标 放置在屏幕顶部,距顶部 20pt,最后水平对齐父视图。

var views = ["tableView":self.tableView!,"logoImageView":logoImageView,"view":self.view]

self.view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:[logoImageView(40)]", options: nil, metrics: nil, views: views))

self.view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:[logoImageView(40)]", options: nil, metrics: nil, views: views))

self.view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|-20-[logoImageView]", options: nil, metrics: nil, views: views))        

self.view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:[view][logoImageView]", options: NSLayoutFormatOptions.AlignAllCenterX, metrics: nil, views: views));

但这是我在 debugger/console.

中得到的错误
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:0x7fa78487e8f0 V:|-(20)-[UIImageView:0x7fa784b29350]   (Names: '|':UIView:0x7fa78373b8e0 )>",
    "<NSLayoutConstraint:0x7fa784886f70 V:[UIView:0x7fa78373b8e0]-(0)-[UIImageView:0x7fa784b29350]>",
    "<NSLayoutConstraint:0x7fa78488caa0 'UIView-Encapsulated-Layout-Height' V:[UIView:0x7fa78373b8e0(667)]>"
)

Will attempt to recover by breaking constraint 
<NSLayoutConstraint:0x7fa784886f70 V:[UIView:0x7fa78373b8e0]-(0)-[UIImageView:0x7fa784b29350]>

如果有人能帮助解释问题出在哪里以及正确的做法是什么,那就太好了NSLayoutFormatOptions

谢谢!

我发现这个很简单:

  1. 当您注意到错误日志时,请按 Pause 启动 lldb 调试会话
  2. 在控制台类型中: expr [(UIImageView *)0x7fa784b29350 setHidden: YES];

您会注意到视图

<NSLayoutConstraint:0x7fa78487e8f0 V:|-(20)-[UIImageView:0x7fa784b29350]>

会消失,所以你会知道它是什么

问题在于这两个约束:

self.view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|-20-[logoImageView]", options: nil, metrics: nil, views: views))        
self.view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:[view][logoImageView]", options: NSLayoutFormatOptions.AlignAllCenterX, metrics: nil, views: views));

第一个说 logoImageView 的顶部应该距离它的父视图顶部 20 点。第二个说 logoImageView 的顶部应该距离 view.

的底部 0 点

问题是 viewlogoImageView 的超视图。你可以看出,因为这个约束中的超级视图(|):

"<NSLayoutConstraint:0x7fa78487e8f0 V:|-(20)-[UIImageView:0x7fa784b29350]   (Names: '|':UIView:0x7fa78373b8e0 )>",

与此约束中的相邻视图相同:

"<NSLayoutConstraint:0x7fa784886f70 V:[UIView:0x7fa78373b8e0]-(0)-[UIImageView:0x7fa784b29350]>",

因此,这两个约束共同要求 view 身高为 20 磅。但是,table 视图为该视图强加了 667 点的高度,如以下约束所示:

"<NSLayoutConstraint:0x7fa78488caa0 'UIView-Encapsulated-Layout-Height' V:[UIView:0x7fa78373b8e0(667)]>"

因此发生了冲突。

我怀疑问题是您将 logoImageView 添加到了错误的视图中,或者您打算在 V:[view][logoImageView] 视觉格式字符串中列出其他视图。