iOS 快速定位约束冲突

[LayoutConstraints] 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 


Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger.
The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in  may also be helpful.

快速定位约束冲突
一般简单界面冲突,我们很容易根据提示找到对应的 View, 但是当你视图层次很深(比如使用 CollectionView 多种 Cell 类型时),你就很难发现是哪个控件产生的冲突。

我们通过 lldb(控制台) 对象地址能快速找到对应控件。

没有断点怎么在 lldb 执行命令
在我们发现冲突的时候,界面可能并没有设置断点,或者不好设置断点来执行 lldb 命令操纵

此时我们只需要点击调试图层按钮,就可以进行命令执行了,不仅可以查看图层,打印视图信息,查看某个视图地址,还可以在 lldb 执行命令。
image.png

根据系统要删除的约束的控件地址,比如转化地址对象并输出属性

 (lldb) po ((UIView *)0x7fb43d20a6e0).subviews
<__NSArrayM 0x6000033baaf0>(
>
)

通过打印子视图就可以看见 view 下面包含Label控件,从而方便定位。

tip: 建议这种情况,终端使用 Objective-C 语法。

根据地址转对象,打印子视图层级
我们通过打印图层层级就可以很容易判断冲突控件属于哪个 View

po [((UIView *)0x7fa5382061c0)  recursiveDescription]

结果

>
   | >

这里可以看到冲突控件下含有一个 带UILabel的UIView,就方便定为到目标视图,然后再去排查和解决冲突。

设置约束冲突断点
如果你记不住,还有一劳永逸的方法,直接捕获冲突断点,且设置打印 UIWindow 图层。

在发生冲突的时候直接借助对象地址定位到控件。

步骤:

  1. 选中 show BreakPoint navigator
  2. 选择左下角 + 添加 Symbolic BreakPoint
  3. 在Symbo填入 UIViewAlertForUnsatisfiableConstraints
  4. Action增加打印图层命令 po [[UIWindow keyWindow] _autolayoutTrace]
  5. 建议勾选断点自动执行,否则每次发生冲突就会触发断点,且此时没有图层打印和定位冲突代码的能力。
注意:Xcode11及以上版本创建的 Swift 项目,由于 ScenceDelegate 的发布,取消了 keyWindow。使用 po [[[UIApplication sharedApplication] windows].firstObject recursiveDescription]或者po [[[UIApplication sharedApplication] windows].firstObject _autolayoutTrace]

Obj-C project

po [[UIWindow keyWindow] _autolayoutTrace]

Swift project

expr -l objc++ -O -- [[UIWindow keyWindow] _autolayoutTrace]

如下图:

image.png

如下图,直接通过搜索地址就可以发现问题控件
image.png

Then I paused execution
image.png

and I changed problematic view's background color with the command (replacing 0x7f88a8cc2050 with the memory address of your object of course)...

Obj-C

expr ((UIView *)0x7f88a8cc2050).backgroundColor = [UIColor redColor]

Swift 3.0

expr -l Swift -- import UIKit
expr -l Swift -- unsafeBitCast(0x7f88a8cc2050, to: UIView.self).backgroundColor = UIColor.red

... and the result It was awesome!

image.png

Simply amazing!

你可能感兴趣的:(iOS 快速定位约束冲突)