调试程序化自动布局约束

时间:2014-09-02 13:33:41

标签: objective-c autolayout nslayoutconstraint

我通过添加子视图和约束(使用CocoaPod PureLayout)完全在代码中创建了我的视图控制器视图。它实际上看起来/功能完全是我想要的,但xcode对我大吼,说其中一个约束是错误的并且它将其删除。如何判断哪些UIViews附加了不良约束?我有很多子视图,我无法从上下文中找出答案。在界面构建器中使用约束时,您可以将UIView命名为打印到调试控制台的内容,但我无法通过代码找到实现此目的的方法。

查看苹果文档:https://developer.apple.com/library/ios/documentation/userexperience/conceptual/AutolayoutPG/ResolvingIssues/ResolvingIssues.html#//apple_ref/doc/uid/TP40010853-CH17-SW14

他们说: "可能很明显哪个观点有问题;如果不是,您可能会发现使用NSView方法_subtreeDescription创建视图层次结构的文本描述很有帮助。

重要说明:_subtreeDescription方法不是公共API;但是,它允许用于调试目的"

这是我正在寻找的吗?如何使用私有API?

2 个答案:

答案 0 :(得分:10)

从iOS 8 SDK开始,现在有一个identifier property on NSLayoutConstraint。请注意,自iOS 7以来,此属性已私下存在(仅限Apple),但现在它已在iOS 8中公开,即使在iOS 7上运行,也可以使用它。

使用此属性,您可以轻松地为约束设置唯一的简短描述以帮助调试。例如,使用PureLayout

NSLayoutConstraint *constraint = [label autoPinEdge:ALEdgeLeft toEdge:ALEdgeRight ofView:imageView];
constraint.identifier = @"Label Left Padding";

// ...or using PureLayout v2.0+:
[[label autoPinEdge:ALEdgeLeft toEdge:ALEdgeRight ofView:imageView] autoIdentify:@"Label Left Padding"];

// PureLayout v2.0+ also supports a block-based version to set an identifier to many constraints at once:
[UIView autoSetIdentifer:@"Constraints to position image view" forConstraints:^{
    // ...a bunch of PureLayout API calls here that create constraints...
}];

然后,如果存在约束异常,您将在控制台中看到此标识符打印在约束旁边。

另一个方便的调试工具:

Apple在名为UIView.h的UIView(在UIConstraintBasedLayoutDebugging中声明)包含一个方法,有一个非常方便的类别:

- (NSArray *)constraintsAffectingLayoutForAxis:(UILayoutConstraintAxis)axis;

您可以在任何视图上调用此方法,传递水平轴或垂直轴(因为每个轴中的约束是独立的),并获取影响沿该轴的位置和大小的所有约束的列表。请注意,Apple说这应该仅用于调试 - 永远不会发送使用此API的代码!

答案 1 :(得分:3)

UIWindow还有一个私有实例方法_autolayoutTrace来转储显示整个视图层次结构的字符串,包括不明确的视图。在看到约束异常后设置断点后,只需在控制台中使用它。您还可以使用符号断点“UIViewAlertForUnsatisfiableConstraints”捕获任何autolayout异常。

查看Facebook的Chisel:https://github.com/facebook/chisel