debugging Auto Layout:Debugging Tricks and Tips

Debugging Tricks and Tips调试技巧和技巧

The following topics describe techniques for gathering and organizing information about your layout, as well as descriptions of some surprising behaviors you may encounter. You may not need to use these techniques on every layout, but they can help you work your way through even the most difficult problems.

下面的主题描述收集和组织有关布局的信息的技术,以及一些可能遇到的令人惊讶的行为的描述。您可能不需要使用这些技术在每一个布局,但他们可以帮助您的工作方式,即使是最困难的问题。

Understanding the Logs理解的日志

Information about views can be printed to the console, either because there is an unsatisfiable layout or because you have explicitly logged constraints using the constraintsAffectingLayoutForAxis: or constraintsAffectingLayoutForOrientation: debugging method.

信息视图可以被打印到控制台,或者是因为有一个永无止境的布局或因为你有明确记录的限制使用constraintsaffectinglayoutforaxis:或constraintsaffectinglayoutfororientation:调试方法。

Either way, you can find a lot of useful information in these logs. Here is the sample output from an unsatisfiable layout error:无论哪种方式,你可以在这些日志中找到很多有用的信息。这是一个永无止境的布局错误输出样本:

  1. 2015-08-26 14:27:54.790 Auto Layout Cookbook[10040:1906606] Unable to simultaneously satisfy constraints.
  2. 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)
  3. (
  4. "<NSLayoutConstraint:0x7a87b000 H:[UILabel:0x7a8724b0'Name'(>=400)]>",
  5. "<NSLayoutConstraint:0x7a895e30 UILabel:0x7a8724b0'Name'.leading == UIView:0x7a887ee0.leadingMargin>",
  6. "<NSLayoutConstraint:0x7a886d20 H:[UILabel:0x7a8724b0'Name']-(NSSpace(8))-[UITextField:0x7a88cff0]>",
  7. "<NSLayoutConstraint:0x7a87b2e0 UITextField:0x7a88cff0.trailing == UIView:0x7a887ee0.trailingMargin>",
  8. "<NSLayoutConstraint:0x7ac7c430 'UIView-Encapsulated-Layout-Width' H:[UIView:0x7a887ee0(320)]>"
  9. )
  10. Will attempt to recover by breaking constraint
  11. <NSLayoutConstraint:0x7a87b000 H:[UILabel:0x7a8724b0'Name'(>=400)]>
  12. Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger.
  13. The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKit/UIView.h> may also be helpful.

This error message shows five conflicting constraints. Not all of these constraints can be true at the same time. You need to either remove one, or convert it to an optional constraint.

此错误消息显示五个相互冲突的约束。并非所有这些约束都可以在同一时间真实。您需要删除一个,或将其转换为可选约束。

Fortunately, the view hierarchy is relatively simple. You have a superview containing a label and a text field. The conflicting constraints set the following relationships:

幸运的是,视图层次结构相对简单。你有一个视图包含一个标签和一个文本字段。冲突约束设置以下关系:

  1. The label’s width is greater than or equal to 400 points.标签的宽度大于或等于400分。

  2. The label’s leading edge is equal to the superview’s leading margin.标签的领先优势等于父视图的领先幅度。

  3. There is an 8-point space between the label and the text field.有标签和文本域之间的一点空间。

  4. The text field’s trailing edge is equal to the superview’s trailing margin.文本域的后缘等于父视图的尾缘。

  5. The superview’s width is set to 320 points.父视图的宽度设置为320点。

The system attempts to recover by breaking the label’s width.系统试图通过打破标签的宽度来恢复。

NOTE

Constraints are written to the console using the Visual Format Language. Even if you never use the Visual Format Language to create your own constraints, you must be able to read and understand it to effectively debug Auto Layout issues. For more information, see Visual Format Language.

使用视觉格式语言将约束写入控制台。即使你从来没有使用可视化格式语言来创建自己的约束,你必须能够阅读和理解它,有效地调试自动布局问题。有关更多信息,请参见可视化格式语言。

Of these constraints, the last one was created by the system. You cannot change it. Furthermore, it creates an obvious conflict with the first constraint. If you superview is only 320 points wide, you can never have a 400-point-wide label. Fortunately, you don’t have to get rid of the first constraint. If you drop its priority to 999, the system still tries to provide the selected width—coming as close as it can while still satisfying the other constraints.

这些约束,最后一个是由系统创建。你不能改变它。此外,它创建了一个明显的冲突与第一个约束。如果你的视图只有320分宽,你永远不可能有400点宽的标签。幸运的是,你不必摆脱第一个约束。如果你将它的优先级降到999,系统仍然试图提供所选择的宽度尽可能接近,同时仍然满足其他约束.

Constraints based on a view’s autoresizing mask (for example, constraints created when translatesAutoresizingMaskIntoConstraints is YES) have additional information about the mask. After the constraint’s address, the log string shows h= followed by three characters, and v= followed by three characters. A - (hyphen) character indicates a fixed value, while an & (ampersand) indicates a flexible value. For the horizontal mask (h=), the three characters indicate the left margin, width, and right margin. For the vertical mask (v=), they indicate the top margin, height, and bottom margin.

基于视图的自动尺寸调整模板的限制(例如,约束创建时,translatesautoresizingmaskintoconstraints是肯定的)有关于面具的附加信息。在约束的地址后,日志字符串显示H =后跟三个字符,和V =其次是三个字符。-(连字符)字符表示一个固定的值,而一个&(&)表示柔性价值。对于水平掩码(H =),三个字符表示左边缘,宽度和右边缘。对于垂直遮罩(V =),他们表示的顶部边缘,高度和底部边距。

For example, consider the log message:例如,考虑日志消息:

  1. <NSAutoresizingMaskLayoutConstraint:0x7ff28252e480 h=--& v=--& H:[UIView:0x7ff282617cc0(50)]>"

This message consists of the following parts:此消息由以下部分组成:

  • NSAutoresizingMaskLayoutConstraint:0x7ff28252e480: The constraint’s class and address. In this example, the class tells you that it is based on the view’s autoresizing mask.NSAutoresizingMaskLayoutConstraint:0x7ff28252e480:约束的类和地址。在这个例子中,类告诉你,它是基于视图的自动尺寸调整面膜。

  • h=--& v=—&: The view’s autoresizing mask. This is the default mask. Horizontally it has a fixed left margin, a fixed width, and a flexible right margin. Vertically it has a fixed top margin, a fixed height, and a flexible bottom margin. In other words, the view’s top left corner and size remain constant when the superview’s size changes.H =——V = -:视图的自动尺寸调整面膜。这是默认的掩码。水平它有一个固定的左边缘,一个固定的宽度,和一个灵活的右边缘。垂直它有一个固定的顶部边缘,一个固定的高度,和一个灵活的底部边距。换句话说,视图的左上角和尺寸保持不变时,父视图的尺寸变化。

  • H:[UIView:0x7ff282617cc0(50)]: The visual format language description of the constraint. In this example, it defines a single view with a constant width of 50 points. This description also contains the class and address of any views affected by the constraint.H:[ UIView:0x7ff282617cc0(50)]:视觉形式语言描述的约束。在本例中,它定义了一个具有50个宽度的单视图。此描述还包含受约束影响的任何视图的类和地址。

Adding Identifiers to the Logs在日志中添加标识符

Although the previous example was relatively easy to understand, longer lists of constraints quickly become hard to follow. You can make the logs easier to read by providing every view and constraint with a meaningful identifier.

虽然前面的例子相对容易理解,但是较长的约束列表很难被跟踪。通过向每个视图和约束提供有意义的标识符,可以使日志更容易阅读。

If the view has an obvious textual component, Xcode uses that as an identifier. For example, Xcode uses a label’s text, a button’s title, or a text field’s placeholder to identify these views. Otherwise, set the view’s Xcode specific label in the Identity inspector. Interface Builder uses these identifiers throughout its interface. Many of them are also displayed in the console logs.

如果视图文本明显的成分,Xcode使用作为标识符。例如,Xcode使用标签的文本,按钮的标题或文本字段的占位符来识别这些观点。否则,在身份检查器设置视图的Xcode特定标签。接口生成器在其接口中使用这些标识符。他们中的许多也显示在控制台日志。

For the constraints, set their identifier property, either programmatically or using the Attribute inspector. Auto Layout then uses these identifiers when it prints information to the console.

对于约束,可以以编程方式或使用属性检查器设置其标识符属性。自动布局,然后使用这些标识符时,打印信息到控制台。

For example, here is the same unsatisfiable constraint error with the identifiers set:例如,这里是一个不可满足的约束错误的标识符集:

  1. 2015-08-26 14:29:32.870 Auto Layout Cookbook[10208:1918826] Unable to simultaneously satisfy constraints.

    2015-08-26 14:29: 32.870自动布局的食谱[ 10208:1918826 ]无法同时满足约束条件。

  2. 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)以下列表中至少有一个约束是你不希望的。试着这样做:(1)看每个约束并试着找出你不期望的;(2)查找添加了不需要的约束或约束的代码并修复它。(注:如果你看到nsautoresizingmasklayoutconstraints,你不明白,请参阅文档UIView的财产translatesautoresizingmaskintoconstraints
  3. (
  4. "<NSLayoutConstraint:0x7b58bac0 'Label Leading' UILabel:0x7b58b040'Name'.leading == UIView:0x7b590790.leadingMargin>",
  5. "<NSLayoutConstraint:0x7b56d020 'Label Width' H:[UILabel:0x7b58b040'Name'(>=400)]>",
  6. "<NSLayoutConstraint:0x7b58baf0 'Space Between Controls' H:[UILabel:0x7b58b040'Name']-(NSSpace(8))-[UITextField:0x7b589490]>",
  7. "<NSLayoutConstraint:0x7b51cb10 'Text Field Trailing' UITextField:0x7b589490.trailing == UIView:0x7b590790.trailingMargin>",
  8. "<NSLayoutConstraint:0x7b0758c0 'UIView-Encapsulated-Layout-Width' H:[UIView:0x7b590790(320)]>"
  9. )
  10. Will attempt to recover by breaking constraint
  11. <NSLayoutConstraint:0x7b56d020 'Label Width' H:[UILabel:0x7b58b040'Name'(>=400)]>
  12. Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger.
  13. The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKit/UIView.h> may also be helpful.

As you can see, these identifiers allow you to quickly and easily recognize your constraints in the log.正如您所看到的,这些标识符允许您快速且轻松地识别日志中的约束。

Visualizing Views and Constraints可视化视图和约束

Xcode provides tools that help you visualize the views and the constraints in your view hierarchy.

To see the views in the simulator:Xcode提供了工具,帮助您可视化视图和视图层次结构的约束。

在模拟器中查看视图:

  1. Run the app in the simulator.在模拟器中运行应用程序。

  2. Switch back to Xcode.切换回Xcode。

  3. Choose Debug > View Debugging > Show Alignment Rectangles. This setting outlines the edges of your views.选择调试>视图调试>显示对齐矩形。此设置概述您的视图的边缘。

    image: ../Art/Show_Alignment_Rectangles_2x.png

The alignment rectangles are the edges used by Auto Layout. Turning this option on lets you quickly spot any alignment rectangles that are unexpectedly resized.

the对齐的矩形边used by are the自动布局。将这个选项让你很快我们任何对齐的矩形光斑that are竟然调整大小。

If you need even more information, click the Debug View Hierarchy button (image: ../Art/Screen Shot 2015-08-26 at 11.35.43 AM.png) in Xcode debug bar. Xcode then displays an interactive view debugger, giving you a number of tools for exploring and interacting with the view hierarchy. When debugging Auto Layout issues, the “Show clipped content” and “Show constraints” options are particularly useful.

如果你需要更的信息,单击debug视图层次按钮(图片:……/艺术/屏幕镜头2015年08月26 at 11.35.43 am.png)在Xcode调试吧。Xcode然后显示互动观调试器,给你a number of Tools for Exploring和相互作用以及视图层次。当调试自动布局问题,“秀剪切高兴”和“秀Constraints”选项是特别有用的。

image: ../Art/Debug_View_Hierarchy_2x.png

Enabling the “Show clipped content” option displays the location of views that may have accidentally been positioned off screen. Enabling the “Show constraint” option shows all the constraints affecting the currently selected view. Both options provide a quick sanity check when things begin behaving oddly.

启用“显示剪辑内容”选项显示可能在屏幕上意外定位的视图的位置。启用“显示约束”选项显示所有影响当前选定视图的约束。当事情开始变得古怪时,这两种选择都能迅速地进行理智的检查。

For more information, see Debug Area Help.有关更多信息,请参见调试区域帮助。

Understanding Edge Cases了解边缘情况

Here are a few edge cases that can cause Auto Layout to behave in unexpected ways:这里有一些边缘的情况下,可能会导致自动布局的行为意想不到的方式:

  • Auto Layout positions views based on their alignment rectangles, not their frame. Most of the time, these values are identical. However, some views may set a custom alignment rectangle to exclude parts of the view (for example, badges) from the layout calculations.自动布局位置视图基于它们的对齐矩形,而不是它们的框架。大多数时候,这些值是相同的。但是,有些视图可以设置自定义对齐矩形以排除布局计算中视图的部分(例如,徽章)。

    For more information, see Aligning Views with Auto Layout in UIView Class Reference.有关更多信息,参见对齐视图与UIView类参考自动布局。

  • In iOS, you can use a view’s transform property to resize, rotate, or move the view; however, these transformations do not affect Auto Layout’s calculations in any way. Auto layout calculates a view’s alignment rectangle based on its untransformed frame.在iOS中,可以使用视图的转换属性来调整大小、旋转或移动视图;但是,这些转换不会以任何方式影响自动布局的计算。自动布局基于其未计算视图的对齐的矩形框。

  • A view can display content outside its bounds. Most of the time, views behave properly and limit their content to their bounds. For performance reasons, however, this is not enforced by the graphics engine. This means that views (and especially views with custom drawing) may be drawn at a different size than their frames.视图可以在其边界之外显示内容。大多数情况下,视图行为正常,并限制其内容的界限。然而,由于性能原因,这不是由图形引擎强制执行的。这意味着视图(特别是与自定义绘图的视图)可以以不同的大小绘制。

    You can identify these bugs by setting the view’s clipsToBounds property to YES or by verifying the size of the view’s frame.你能找出这些错误,设置视图的clipstobounds属性是通过验证视图大小的框架。

  • The NSLayoutAttributeBaselineNSLayoutAttributeFirstBaseline, and NSLayoutAttributeLastBaseline attributes correctly align the text only when all the views are displayed at their intrinsic content height. If one of the views is stretched or shrunk vertically, its text may appear in the wrong position.          NSLayoutattributebaseline nslayoutattributefirstbaseline,茶,和nslayoutattributelastbaseline the text only when属性正确align are displayed at their所有视图的内在内容的高度。if one of the is shrunk vertically伸长前视图,其文本可能出现在错误的位置。

  • Constraint priorities act as global properties across the entire view hierarchy. You can often simplify your layout by grouping views inside a stack view, a layout guide, or a dummy view; however, this approach does not encapsulate the contained views’ priorities. Auto Layout continues to compare priorities inside the group with priorities outside the group (or even priorities inside other groups).约束优先级在整个视图层次结构中充当全局属性。通常可以通过在堆栈视图、布局指南或虚拟视图中分组视图来简化布局,但是,这种方法并没有封装包含视图的优先级。自动布局继续比较组内优先级与组外优先级(甚至优先于其他组内)。

  • Aspect ratio constraints allow horizontal and vertical constraints to interact. Normally, the horizontal and vertical layouts are calculated separately. However, if you constrain a view’s height relative to its width, you’ve created a connection between the vertical and horizontal constraints: They can now affect and conflict with each other. These interactions greatly increase the complexity of your layout and can lead to unexpected conflicts between unrelated parts of your layout.水平和垂直约束方面比allow巴巴多斯的互动。通常,水平和垂直布局are the分别计算。然而,如果你有view'的相对高度constrain to its宽度,你已经创建了连接的垂直和水平之间的约束:他们现在可以影响and conflict with each other。这些相互作用的复杂性极大地增加布局and can lead to意想不到的冲突之间的布局与我无关的股份。

iOS Android Appcan WeChat
原文地址:https://www.cnblogs.com/zyingn/p/debuggingAutoLayout__DebuggingTricksAndTips.html