Unsatisfiable Layouts永无止境的布局
Unsatisfiable layouts occur when the system cannot find a valid solution for the current set of constraints. Two or more required constraints conflict, because they cannot all be true at the same time.
永无止境的布局出现系统无法找到制约当前设置一个有效的解决方案。两个或多个必需的约束冲突,因为它们不能同时都是真实的。
Identifying Unsatisfiable Constraints识别不可满足的约束条件
Often, Interface Builder can detect conflicts at design time. On these occasions, Interface Builder displays the error in a number of ways:
通常,接口生成器可以在设计时检测冲突。在这些情况下,接口生成器以多种方式显示错误:
-
All the conflicting constraints are drawn on the canvas in red.所有冲突的约束绘制在画布上的红色。
-
Xcode lists the conflicting constraints as warnings in the issue navigator.Xcode列出冲突限制在问题导航警告。
-
Interface Builder displays a red disclosure arrow in the upper right corner of the document outline.界面生成器在文档大纲的右上角显示红色的显示箭头。
Click the disclosure arrow to display a list of all the Auto Layout issues in the current layout.
单击“显示箭头”显示当前布局中所有自动布局问题的列表。
Interface Builder can often recommend fixes for these issues. For more information, see Resolving Layout Issues for a View Controller, Window, or Root View in Auto Layout Help.接口生成器通常可以为这些问题推荐修复程序。有关更多信息,请参见解决自动布局帮助中的视图控制器、窗口或根视图的布局问题。
NOTE
Although the instant feedback provided by Interface Builder makes it much easier to create valid layouts, it cannot find all possible layout errors.
虽然界面生成器提供的即时反馈使创建有效的布局更加容易,但无法找到所有可能的布局错误。
For example, Interface Builder detects conflicts only at the canvas’s current size; however, some conflicts occur only when the root view is stretched or shrunk beyond a certain point (or when the content expands or shrinks beyond a certain point). Interface Builder cannot detect these errors.
例如,接口生成器仅在画布的当前大小检测冲突,但是,只有当根视图拉伸或收缩超过某一点(或内容扩展或收缩超过某一点)时,才会发生冲突。接口生成器无法检测这些错误。
So, even though you should always fix all the issues that Interface Builder identifies, fixing the obvious errors is not sufficient. You still need to perform runtime testing across the full range of screen sizes, orientations, dynamic type sizes, and languages that you intend to support.
因此,即使您总是应该修复接口生成器标识的所有问题,但修复明显的错误是不够的。您仍然需要在整个屏幕大小、方向、动态类型大小和您想支持的语言上执行运行时测试。
When the system detects a unsatisfiable layout at runtime, it performs the following steps:
当系统检测到一个永无止境的布局时,它执行以下步骤:
-
Auto Layout identifies the set of conflicting constraints.自动布局标识冲突约束集。
-
It breaks one of the conflicting constraints and checks the layout. The system continues to break constraints until it finds a valid layout.它打破了一个相互冲突的约束和检查布局。系统继续打破约束,直到找到有效的布局。
-
Auto Layout logs information about the conflict and the broken constraints to the console.
自动布局将冲突和损坏的约束记录到控制台。
This fallback system lets the app proceed, while still attempting to present something meaningful to the user. However, the effect of breaking constraints can vary greatly from layout to layout, or even from build to build.
该备份系统允许应用程序继续进行,同时仍试图向用户呈现一些有意义的功能。然而,突破约束的效果可以大大不同,从布局到布局,甚至从建立到建立。
In many cases, the missing constraints may not have any visible effect. The view hierarchy appears exactly as you expected. In other cases, the missing constraints can cause entire sections of the view hierarchy to be misplaced, missized, or to disappear entirely.
在许多情况下,缺少的约束可能没有任何可见的效果。视图层次结构与您预期的完全一样。在其他情况下,缺少的约束会导致视图层次的整个部分是错误的,missized,或完全消失。
It is often tempting to ignore errors when they don’t have an obvious effect—after all, they don’t change the app’s behavior. However, any change to the view hierarchy or SDK could also alter the set of broken constraints, suddenly producing an obviously broken layout.
它往往是诱人的忽视错误时,他们没有一个明显的效果毕竟,他们不会改变应用程序的行为。但是,视图层次结构或SDK的任何更改也可能改变约束的约束,突然产生明显的破坏布局。
Therefore, always fix unsatisfiable constraint errors when you detect them. To help ensure that you catch nonobvious errors during testing, set a symbolic breakpoint for UIViewAlertForUnsatisfiableConstraints
.
因此,总是固定不可满足的约束错误,当你发现他们。确保你赶上不明显的错误,在测试过程中,对于uiviewalertforunsatisfiableconstraints设定一个象征性的断点。
Preventing Unsatisfiable Constraints防止不可满足的约束条件
Unsatisfiable constraints are relatively easy to fix. The system tells you when unsatisfiable constraints occur and provides you with a list of conflicting constraints.
不可满足的约束相对容易解决。系统告诉你不可满足的约束时发生,为你提供了一个列表的约束冲突。
As soon as you know about the error, the solution is typically very straightforward. Either remove one of the constraints, or change it to an optional constraint.
一旦你知道错误,解决方案通常是非常简单的。要么删除一个约束,要么将其更改为可选约束。
There are, however, a few common issues worth examining in more detail:
然而,有一些常见的问题值得更详细地研究:
-
Unsatisfiable constraints often occur when programmatically adding views to the view hierarchy. 不可满足的约束经常发生在以编程方式添加视图的视图层次结构。
By default, new views have their
translatesAutoresizingMaskIntoConstraints
property set toYES
. Interface Builder automatically sets this property toNO
when you begin drawing constraints to a view in the canvas. However, when you’re programmatically creating and laying out your views, you need to set the property toNO
before adding your own, custom constraints.默认情况下,新的观点,他们的translatesautoresizingmaskintoconstraints属性设置为“是”。当您开始对画布中的视图进行约束时,接口生成器会自动将此属性设置为“否”。但是,当您以编程方式创建和布局视图时,需要在添加自定义约束之前将属性设置为“否”。 -
Unsatisfiable constraints often occur when a view hierarchy is presented in a space that is too small for it.
不可满足的约束往往发生在视图层次中,它是空间太小了。
You can usually predict the minimum amount of space that your view has access to and design your layout appropriately. However, both internationalization and dynamic type can cause the view’s content to be much bigger than expected. As the number of possible permutations grows, it becomes increasingly difficult to guarantee that your layout will work in all situations.您通常可以预测您的视图可以访问的最小空间,并适当地设计布局。然而,国际化和动态类型都会导致视图的内容比预期的要大得多。随着可能排列的数量的增加,它变得越来越难以保证您的布局将在所有情况下工作。
Instead, you may want to build in failure points, so that your layout fails in a predictable, controlled manner.相反,你可能想建立在故障点,使您的布局在一个可预见的,可控的方式失败。
Consider converting some of your required constraints into high-priority optional constraints. These constraints lets you control where your layout will break when a conflict occurs.考虑将一些必需的约束转换成高优先级的可选约束。这些约束允许您控制冲突发生时布局的中断位置。
For example, give your failure point a priority of
999
. Under most circumstances, this high-priority constraint acts as if it were required; however, when a conflict occurs, the high-priority constraint breaks, protecting the rest of your layout.例如,给你的失败点999的优先级。在大多数情况下,这个高优先级的约束行为,如果它是必需的,但是,当冲突发生时,高优先级的约束休息,保护其余的布局。Similarly, avoid giving views with an intrinsic content size a required content-hugging or compression-resistance priority. Typically, a control’s size acts as an ideal failure point. The control can be a little bigger or a little smaller without having any meaningful effect on the layout.同样,避免用固有内容大小给视图一个需要的内容拥抱或压缩抵抗优先级。通常情况下,控制的大小作为一个理想的故障点。控件可以稍大或稍小,但对布局没有任何有意义的影响。
Yes, there are controls that should only be displayed at their intrinsic content size; however, even in these cases it is usually better to have a control that is a few points off rather than just letting your layout break in unpredictable ways.是的,有一些控件应该只显示在其内在内容的大小,但是,即使在这些情况下,它通常是更好的有一个控制是几点关闭,而不是让你的布局打破不可预知的方式。