Anatomy of a Constraint

剖析约束

The layout of your view hierarchy is defined as a series of linear equations. Each constraint represents a single equation. Your goal is to declare a series of equations that has one and only one possible solution.

A sample equation is shown below.

视图层次中的布局是以一系列的线性方程来定义的。 每个约束表示一个方程。 你的目标就是声明一系列的方程,并且每个方程有且仅有一个可能的解决方法。 以下是一个方程:

image: ../Art/view_formula.pdf

This constraint states that the red view’s leading edge must be 8.0 points after the blue view’s trailing edge. Its equation has a number of parts:

该约束表明红色视图的开头边界和蓝色视图的结尾边界之间必须有8点的间隔。该方程有以下部分组成:

  • Item 1. The first item in the equation—in this case, the red view. The item must be either a view or a layout guide.

                 方程中的第一项---在这里指的是红色视图。 该项必须是一个视图或是一个布局导航。

  • Attribute 1. The attribute to be constrained on the first item—in this case, the red view’s leading edge.

                 对第一项进行限制的属性---在这里,指的是红色视图的开头 边界。

  • Relationship. The relationship between the left and right sides. The relationship can have one of three values: equal, greater than or equal, or less than or equal. In this case, the left and right side are equal.

                左右两边的关系。 该关系可以是"=", ">=","<=". 在这里,左右两边是相等的关系。

  • Multiplier. The value of attribute 2 is multiplied by this floating point number. In this case, the multiplier is 1.0.

          属性2的值乘以该浮点乘数。  在这里,乘数是1.0。            

  • Item 2. The second item in the equation—in this case, the blue view. Unlike the first item, this can be left blank.

         方程中第二项---在这里是指蓝色视图。 不像第一项,该项可以是空的。 

  • Attribute 2. The attribute to be constrained on the second item—in this case, the blue view’s trailing edge. If the second item is left blank, this must be Not an Attribute.

            对第二项进行限制的属性2---在这里是指蓝色视图的右边界。 如果第二项是空的,该属性2 不能为一个属性。

  • Constant. A constant, floating-point offset—in this case, 8.0. This value is added to the value of attribute 2.

              一个常量,在这里是浮点位移,8.0。该值被加到属性2的值上。

Most constraints define a relationship between two items in our user interface. These items can represent either views or layout guides. Constraints can also define the relationship between two different attributes of a single item, for example, setting an aspect ratio between an item’s height and width. You can also assign constant values to an item’s height or width. When working with constant values, the second item is left blank, the second attribute is set to Not An Attribute, and the multiplier is set to 0.0.

大多数约束定义了用户界面中2个对象(items)之间的一种关系。 这些对象可以是视图或者布局导航。 约束还可以定义一个对象中两个不同属性的关系, 比如设置一个对象的长宽比, 你还可以给一个对象的长宽设定一个常量值。 当对象的属性是常量值,第二项是空的时,属性2不能是一个属性,并且乘数设为0.0。

Auto Layout Attributes

自动布局属性

In Auto Layout, the attributes define a feature that can be constrained. In general, this includes the four edges (leading, trailing, top, and bottom), as well as the height, width, and vertical and horizontal centers. Text items also have one or more baseline attributes.

在自动布局中,各个属性都有一个功能,那就是它们可以被约束。 通常,这些约束包括四条边(开头,结尾,上,下),高度,宽度,以及纵向横向中心等。 文本对象还有一个或多个下划线(baseline)属性。

image: ../Art/attributes_2x.png

For the complete list of attributes, see the NSLayoutAttribute enum.

完整的属性列表,请参照 NSLayoutAttribute

NOTE

注意:

Although both OS X and iOS use the NSLayoutAttribute enum, they define slightly different sets of values. To see the full list of attributes, be sure you are looking at the correct platform’s documentation.

尽管OS X和iOS都使用 NSLayoutAttribute, 但是它们的值有轻微的不同。当你查看完整的属性列表时,请确保你查看了正确的平台文档。

Sample Equations

示例方程

The wide range of parameters and attributes available to these equations lets you create many different types of constraints. You can define the space between views, align the edge of views, define the relative size of two views, or even define a view’s aspect ratio. However, not all attributes are compatible.

这些方程可以使用大范围的参数和属性,它们可以让你创建很多不同类型的约束。你可以定义视图件的间隔,视图边界的对齐,定义两个视图之间的相对尺寸,甚至定义一个视图的长宽比。 但是,并不是所有的属性都是兼容(compatible)的。

There are two basic types of attributes. Size attributes (for example, Height and Width) and location attributes (for example, Leading, Left, and Top). Size attributes are used to specify how large an item is, without any indication of its location. Location attributes are used to specify the location of an item relative to something else. However, they carry no indication of the item’s size.

目前有两种基本类型的属性。 尺寸属性(比如,高和宽等)以及位置属性(比如,开头,左,上等)。 尺寸属性用来指定对象有多大,它不声明对象的位置。 位置属性则用来指定对象相对于别的对象的位置。但是它们却不声明任何该对象的尺寸。

With these differences in mind, the following rules apply:

带着这些差异,再看看以下规则:

  • You cannot constrain a size attribute to a location attribute.

     你不能把一个尺寸属性约束加到一个位置属性。

  • You can only assign constant values to size attributes.

     你只可以把常量值分配给尺寸属性。

  • For location attributes, you cannot constrain vertical attributes to horizontal attributes.

     对于位置属性,你不能把垂直属性约束加到水平属性约束。

  • For location attributes, you cannot constrain Leading or Trailing attributes to Left or Right attributes.

    对于位置属性, 你不能把开头或结尾属性约束加到左边或右边属性约束。

For example, setting an item’s Top to the constant value 20.0 has no meaning without additional context. You must always define an item’s location attributes in relation to other items, for example, 20.0 points below the superview’s Top. However, setting an item’s Height to 20.0 is perfectly valid. For more information, seeInterpreting Values.

比如,如果没有额外的环境,给一个对象的上边设置了一个20.0的常量没有意义。你必须总是定义一个对象的位置属性相对于另外的对象,比如,该对象跟父视图的上边界低20.0个点。 但是,把一个对象的高度设为20.0却是完全有效的。更多信息,请看Interpreting Values

Listing 3-1 shows sample equations for a variety of common constraints.

列表3-1 显示了各种各样通用的示例方程约束。

NOTE

注意:

All the example equations in this chapter are presented using pseudocode. To see real constraints using real code, see Programmatically Creating Constraints or Auto Layout Cookbook.

本章所有的示例方程都是用伪代码(pseudocode)形式呈现的。要想查看真实代码所表示的真实约束,请看Programmatically Creating Constraints 或者 Auto Layout Cookbook.

Listing 3-1Sample equations for common constraints

  1. // Setting a constant height
  2. View.height = 0.0 * NotAnAttribute + 40.0
  3. // Setting a fixed distance between two buttons
  4. Button_2.leading = 1.0 * Button_1.trailing + 8.0
  5. // Aligning the leading edge of two buttons
  6. Button_1.leading = 1.0 * Button_2.leading + 0.0
  7. // Give two buttons the same width
  8. Button_1.width = 1.0 * Button_2.width + 0.0
  9. // Center a view in its superview
  10. View.centerX = 1.0 * Superview.centerX + 0.0
  11. View.centerY = 1.0 * Superview.centerY + 0.0
  12. // Give a view a constant aspect ratio
  13. View.height = 2.0 * View.width + 0.0

Equality, Not Assignment

相等,不分配

It’s important to note that the equations shown in Note represent equality, not assignment.

请注意,示例中的方程式表示相等,不是分配。

When Auto Layout solves these equations, it does not just assign the value of the right side to the left. Instead, it calculates the value for both attribute 1 and attribute 2 that makes the relationship true. This means we can often freely reorder the items in the equation. For example, the equations in Listing 3-2 are identical to their counterparts in Note.

当自动布局解决这些方程式,它不仅仅是把右边的值分配给左边。而是,它计算了属性1和属性2的值,并让该方程式的关系变成true. 这意味着我们可以常常自由的变换方程式中得对象。 比如,列表3-2中的方程式跟列表3-1中的方程式是一样的。

Listing 3-2Inverted equations

  1. // Setting a fixed distance between two buttons
  2. Button_1.trailing = 1.0 * Button_2.leading - 8.0
  3. // Aligning the leading edge of two buttons
  4. Button_2.leading = 1.0 * Button_1.leading + 0.0
  5. // Give two buttons the same width
  6. Button_2.width = 1.0 * Button.width + 0.0
  7. // Center a view in its superview
  8. Superview.centerX = 1.0 * View.centerX + 0.0
  9. Superview.centerY = 1.0 * View.centerY + 0.0
  10. // Give a view a constant aspect ratio
  11. View.width = 0.5 * View.height + 0.0

NOTE

注意:

When reordering the items, make sure you invert the multiplier and the constant. For example, a constant of8.0 becomes -8.0. A multiplier of 2.0 becomes 0.5. Constants of 0.0 and multipliers of 1.0 remain unchanged.

当你重新给对象排序时,确保你已经倒置了乘数和常量。 比如, 把常量8.0变成-8.0. 把乘数2.0变成0.5. 常量0.0 和乘数0.0保持不变。

You will find that Auto Layout frequently provides multiple ways to solve the same problem. Ideally, you should choose the solution that most clearly describes your intent. However, different developers will undoubtedly disagree about which solution is best. Here, being consistent is better than being right. You will experience fewer problems in the long run if you choose an approach and always stick with it. For example, this guide uses the following rules of thumb:

你将发现自动布局常常提供不同方法来解决同一个问题。 最好,你应该选择一中最能描述你的意向的解决方法。但是,不同的开发者毫不迟疑地选择不同的最好解决方法。 在这里,我要说选择你一贯的解决方法比选择正确的更好。 如果你选择一种方法并一直使用它,从长期来看你将减少很多问题。 比如, 请看以下规则:

  1. Whole number multipliers are favored over fractional multipliers.

    整数乘数比小数乘数好。 

  2. Positive constants are favored over negative constants.

     正常量比负常量好。

  3. Wherever possible, views should appear in layout order: leading to trailing, top to bottom.

     只要可能,不管在哪,视图都应该以开头,结尾,上,下顺序出现。

Creating Nonambiguous, Satisfiable Layouts

创建清晰(Nonambiguous)满足的布局

When using Auto Layout, the goal is to provide a series of equations that have one and only one possible solution. Ambiguous constraints have more than one possible solution. Unsatisfiable constraints don’t have valid solutions.

当你使用自动布局时,目标是提供一系列的方程式,而这些方程式有且只有一种解决方法。 模糊地约束都不止有一个可能的解决方法。 不满足的约束没有有效的解决方法。

In general, the constraints must define both the size and the position of each view. Assuming the superview’s size is already set (for example, the root view of a scene in iOS), a nonambiguous, satisfiable layout requires two constraints per view per dimension (not counting the superview). However, you have a wide range of options when it comes to choosing which constraints you want to use. For example, the following three layouts all produce nonambiguous, satisfiable layouts (only the horizontal constraints are shown):

一般来讲,约束必须同时定义每个视图的尺寸和位置。 假设父视图的尺寸已经设置好(比如,iOS屏幕的根视图),一个清晰的满足的布局需要为每个视图每个尺寸(dimension)设置两个约束(不计算父视图)。但是,当你需要选择该使用什么约束时,你有大范围的选择。 比如,以下三个布局都产生清晰的,满足的布局(仅显示水平约束):

image: ../Art/constraint_examples.pdf

  • The first layout constrains the view’s leading edge relative to its superview’s leading edge. It also gives the view a fixed width. The position of the trailing edge can then be calculated based on the superview’s size and the other constraints.

     第一个布局约束了视图的开始边界,它对照父视图的开始边界而设置。 它还给视图设置了一个固定宽度。 结束边界的位置可以根据父视图的尺寸计算出来,其它约束也是。

  • The second layout constrains the view’s leading edge relative to its superview’s leading edge. It also constrains the view’s trailing edge relative to the superview’s trailing edge. The view’s width can then be calculated based on the superview’s size and the other constraints.

     第二个布局约束了视图相对于它的父视图的开始边界。它还约束了视图相对于父视图的结束边界。然后,视图的宽度就可以根据父视图的尺寸计算出来,其它约束也是。

  • The third layout constrains the view’s leading edge relative to its superview’s leading edge. It also center aligns the view and superview. Both the width and trailing edge’s position can then be calculated based on the superview’s size and the other constraints.

    第三个布局约束了视图相对于其父视图的开始边界。 它还让视图的中心跟父视图的中心对齐。然后, 视图的宽度和结束边界位置都可以根据父视图的尺寸计算出来,其它约束也是。

Notice that each layout has one view and two horizontal constraints. In each case, the constraints fully define both the width and the horizontal position of the view. That means all of the layouts produce a nonambiguous, satisfiable layout along the horizontal axis. However, these layouts are not equally useful. Consider what happens when the superview’s width changes.

请注意每个布局都有一个视图和两个水平约束。 每种解决方法,约束都充分地同时定义了视图的宽度和水平位置。 这说明所有的布局在水平轴方向上都产生一个清晰的,满足的布局。但是,这些布局效果并不一样,想象一下当父视图宽度发生改变时将会发生什么?

In the first layout, the view’s width does not change. Most of the time, this is not what you want. In fact, as a general rule, you should avoid assigning constant sizes to views. Auto Layout is designed to create layouts that dynamically adapt to their environment. Whenever you give a view a fixed size, you short circuiting that ability.

在第一个布局中,视图的宽度不会改变。 大多数时候,这都不是你想要的。 事实上,一般来讲,你应该避免给视图分配固定尺寸。 自动布局是用来动态改变布局的尺寸以适应它们的环境。 任何时候你给一个视图固定了尺寸,就削弱了自动布局的能力。

It may not be obvious, but the second and third layouts produce identical behaviors: They both maintain a fixed margin between the view and its superview as the superview’s width changes. However, they are not necessarily equal. In general, the second example is easier to understand, but the third example may be more useful, especially when you are center aligning a number of items. As always, choose the best approach for your particular layout.

或许不是很明显,但是第二第三个布局产生一样的行为:即使父视图的尺寸发生改变,它们都让视图和父视图的边距保持不变。但是,它们也未必一样。 通常,第二个布局更容易理解,但是第三个布局可能更有用, 特别是当你把几个对象都设置为中心对齐时。 与往常一样,选择适合你特定布局的最佳方法。

Now consider something a little more complicated. Imagine you want to display two views, side by side, on an iPhone. You want to make sure that they have a nice margin on all sides and that they always have the same width. They should also correctly resize as the device rotates.

现在考虑一些更复杂的情况。 想象你想要在iPhone上显示两个视图,一边一个。你想要确保它们所有边界都有一个好的边距,而且边距永远保持不变,即使设备方向发生改变。

The following illustrations show the views, in portrait and landscape orientation:

以下是视图的垂直和水平方向的图示:

image: ../Art/Blocks_Portrait_2x.pngimage: ../Art/Blocks_Landscape_2x.png

So what should these constraints look like? The following illustration shows one straightforward solution:

那么这些约束该怎么设置呢?下图演示了一种简单的解决方法:

image: ../Art/two_view_example_1_2x.png

The above solution uses the following constraints:

以上方法使用了以下约束:

  1. // Vertical Constraints
  2. Red.top = 1.0 * Superview.top + 20.0
  3. Superview.bottom = 1.0 * Red.bottom + 20.0
  4. Blue.top = 1.0 * Superview.top + 20.0
  5. Superview.bottom = 1.0 * Blue.bottom + 20.0
  6. // Horizontal Constraints
  7. Red.leading = 1.0 * Superview.leading + 20.0
  8. Blue.leading = 1.0 * Red.trailing + 8.0
  9. Superview.trailing = 1.0 * Blue.trailing + 20.0
  10. Red.width = 1.0 * Blue.width + 0.0

Following the earlier rule of thumb, this layout has two views, four horizontal constraints, and four vertical constraints. While this isn’t an infallible guide, it is a quick indication that you’re on the right track. More importantly, the constraints uniquely specify both the size and the location of both of the views, producing a nonambiguous, satisfiable layout. Remove any of these constraints, and the layout becomes ambiguous. Add additional constraints, and you risk introducing conflicts.

参照之前的规则,该布局有两个视图,四个水平约束,以及四个垂直约束。但这也并不是绝对的指导,它只是说明你已经在对的方向上了。 更重要的事,这些约束单独地指定两个视图的尺寸和位置,生成一个清晰满足的布局。删除这些约束中的任何一个,该布局就变成了不清晰的布局。 添加另外的约束,那你的布局就有冲突的风险。

Still, this is not the only possible solution. Here is an equally valid approach:

但是,这仍然不是唯一可能的解决办法。以下是一个效果的方法:

image: ../Art/two_view_example_2_2x.png

Instead of pinning the top and bottom of the blue box to its superview, you align the top of the blue box with the top of the red box. Similarly, you align the bottom of the blue box with the bottom of the red box. The constraints are shown below.

除了为红蓝视图分别指定相对于父视图的上下边界,你可以让蓝视图的上下边界跟红视图相对齐。 以下是这些约束的方程式:

  1. // Vertical Constraints
  2. Red.top = 1.0 * Superview.top + 20.0
  3. Superview.bottom = 1.0 * Red.bottom + 20.0
  4. Red.top = 1.0 * Blue.top + 0.0
  5. Red.bottom = 1.0 * Blue.bottom + 0.0
  6. //Horizontal Constraints
  7. Red.leading = 1.0 * Superview.leading + 20.0
  8. Blue.leading = 1.0 * Red.trailing + 8.0
  9. Superview.trailing = 1.0 * Blue.trailing + 20.0
  10. Red.width = 1.0 * Blue.width + 0.0

The example still has two views, four horizontal constraints, and four vertical constraints. It still produces a nonambiguous, satisfiable layout.

该示例依旧有两个视图,四个水平约束,以及四个垂直约束。它还是生成一个清晰满足的布局。

BUT WHICH IS BETTER?

但是哪个更好呢?

These solutions both produce valid layouts. So which is better?

这两个方法都生成有效地布局,但是哪个方法更好呢?

Unfortunately, it is virtually impossible to objectively prove that one approach is strictly superior to the other. Each has its own strengths and weaknesses.

不幸地是,几乎不可能证明其中一个方法明显比另个方法好。 每个方法都有自己的长处和弱点。

The first solution is more robust when a view is removed. Removing a view from the view hierarchy also removes all the constraints that reference that view. So, if you remove the red view, the blue view is left with three constraints holding it in place. You need to add only a single constraint and you have a valid layout again. In the second solution, removing the red view would leave the blue view with only a single constraint.

当一个视图被删除时,第一个方法比较结实。从视图层次里删除一个视图就同时删除了该视图引用的所有约束。 因此,如果你删除了红色视图,蓝色视图同样可以拥有它的三个约束。 你只需要再增加一个约束,就又产生一个有效布局。 而第二种方法,当你删除红色视图之后,蓝色视图就只剩下一个约束。

On the other hand, in the first solution, If you want the top and bottom of the views to align, you must make sure their top and bottom constraints use the same constant value. If you change one constant, you must remember to change the other as well.

另一方面,在第一种方法中,如果想要红蓝视图的上部和底部对齐,你必须确保它们的上部和底部使用了同样的常量值。 如果你更改了一个常量,你必须记得修改其它值。

Constraint Inequalities

约束不等式

So far, all of the samples have shown constraints as equalities, but this is only part of the story. Constraints can represent inequalities as well. Specifically, the constraint’s relationship can be equal to, greater than or equal to, or less than or equal to.

到目前为止,所有示例中的约束都是等式,但是这只是一部分。 约束也可以表示不等式。 明确地说,约束的关系可以是"=", ">=","<="。

For example, you can use constraints to define the minimum or maximum size for a view (Listing 3-3).

比如,你可以使用约束来定义一个视图的最小或最大尺寸(列表3-3)。

Listing 3-3Assigning a minimum and maximum size

  1. // Setting the minimum width
  2. View.width >= 0.0 * NotAnAttribute + 40.0
  3. // Setting the maximum width
  4. View.width <= 0.0 * NotAnAttribute + 280.0

As soon as you start using inequalities, the two constraints per view per dimension rule breaks down. You can always replace a single equality relationship with two inequalities. In Listing 3-4, the single equal relationship and the pair of inequalities produce the same behavior.

只要你开始使用不等式,两个约束一个试图一个尺寸的规则就被打破了。 你总是可以用两个不等式代替一个等式。 在列表3-4中,等式和两个不等式产生一样的行为。

Listing 3-4Replacing a single equal relationship with two inequalities

  1. // A single equal relationship
  2. Blue.leading = 1.0 * Red.trailing + 8.0
  3. // Can be replaced with two inequality relationships
  4. Blue.leading >= 1.0 * Red.trailing + 8.0
  5. Blue.leading <= 1.0 * Red.trailing + 8.0

The inverse is not always true, because two inequalities are not always equivalent to a single equals relationship. For example, the inequalities in Listing 3-3 limit the range of possible values for the view’s width—but by themselves, they do not define the width. You still need additional horizontal constraints to define the view’s position and size within this range.

Constraint Priorities

约束优先权

By default, all constraints are required. Auto Layout must calculate a solution that satisfies all the constraints. If it cannot, there is an error. Auto Layout prints information about the unsatisfiable constraints to the console, and chooses one of the constraints to break. It then recalculates the solution without the broken constraint. For more information, see Unsatisfiable Layouts.

默认情况下,所有的约束都需要。 自动布局必须计算一种方法来满足所有的约束。 如果不可能,则会发生一个错误。 自动布局把不满足的约束打印到console(控制台),同时选择它们中的一个约束打破它。 然后,自动布局重新计算满足所有约束,除了被打破约束之外所有约束的方法。更多信息,请看Unsatisfiable Layouts

You can also create optional constraints. All constraints have a priority between 1 and 1000. Constraints with a priority of 1000 are required. All other constraints are optional.

When calculating solutions, Auto Layout attempts to satisfy all the constraints in priority order from highest to lowest. If it cannot satisfy an optional constraint, that constraint is skipped and it continues on to the next constraint.

Even if an optional constraint cannot be satisfied, it can still influence the layout. If there is any ambiguity in the layout after skipping the constraint, the system selects the solution that comes closest to the constraint. In this way, unsatisfied optional constraints act as a force pulling views towards them.

Optional constraints and inequalities often work hand-in-hand. For example, in Listing 3-4 you can provide different priorities for the two inequalities. The greater-than-or-equal relationship could be required (priority of 1000), and the less-than-or-equal relationship has a lower priority (priority 250). This means that the blue view cannot be closer than 8.0 points from the red. However, other constraints could pull it farther away. Still, the optional constraint pulls the blue view towards the red view, ensuring that it is as close as possible to the 8.0-point spacing, given the other constraints in the layout.

你还可以创建可选的约束。 所有的约束都有一个1-1000之间的优先值。 优先值为1000的约束是必要约束,其它约束为可选约束。

当自动布局计算解决方法时,它会从优先值高的约束开始尝试满足所有的约束。如果它不能满足一个可选的约束,它就会跳过这个约束继续满足下个约束。

即使一个可选约束不能被满足,它也还是影响着布局。如果自动布局跳过可选约束后,布局变成模棱两可,系统会选择最接近约束的解决方法。 这个方法,不满足的可选约束就像一个拉力把视图拉向它们。

NOTE

注意:

Don’t feel obligated to use all 1000 priority values. In fact, priorities should general cluster around the system-defined low (250), medium (500), high (750), and required (1000) priorities. You may need to make constraints that are one or two points higher or lower than these values, to help prevent ties. If you’re going much beyond that, you probably want to reexamine your layout’s logic.

不用觉得必须使用所有的1000个优先权。 事实上,优先值通常应该聚集在low(250), medium(500), high(750)和required(1000)值周围。 你或许需要让约束的优先值比这些值高或低1-2点,用来帮助阻止被绑定(help prevent ties.)。 如果你把优先值设置为远远超出那值,那么你很可能想要重新检查你的布局逻辑。

Intrinsic Content Size

内在内容尺寸

So far, all of the examples have used constraints to define both the view’s position and its size. However, some views have a natural size given their current content. This is referred to as their intrinsic content size. For example, a button’s intrinsic content size is the size of its title plus a small margin.

到目前为止,所有的示例都使用约束来定义视图的位置和它的尺寸。 但是,一些视图本身就有一个内在的内容尺寸。 这就是它们的内在内容尺寸。 比如,一个按钮的内在内容尺寸是它的标题尺寸+一个小边距。

Not all views have an intrinsic content size. For views that do, the intrinsic content size can define the view’s height, its width, or both. Some examples are listed in Table 3-1.

并不是所有的视图都有一个内在内容尺寸。 对于有内在内容尺寸的视图,该尺寸会定义视图的高度,它的宽度或者两者都定义。 表格3-1列出了其中一些视图:

Table 3-1Intrinsic content size for common controls表格 3-1 通用控件的内在固有尺寸

View

Intrinsic content size

UIView and NSView

No intrinsic content size.

没有内在固有尺寸。

Sliders

Defines only the width (iOS).

只定义了宽度(iOS)。

Defines the width, the height, or both—depending on the slider’s type (OS X).

定义宽度,高度或两者---根据滑动条的类型(OS X)。

Labels, buttons, switches, and text fields

Defines both the height and the width.

同时定义了高度和宽度。

Text views and image views

Intrinsic content size can vary.

内在固有尺寸能改变。

The intrinsic content size is based on the view’s current content. A label or button’s intrinsic content size is based on the amount of text shown and the font used. For other views, the intrinsic content size is even more complex. For example, an empty image view does not have an intrinsic content size. As soon as you add an image, though, its intrinsic content size is set to the image’s size.

内在固有尺寸是基于视图的当前内容而定的。 一个标签或按钮的内在固有尺寸是根据显示的文本和选用的字体。 对于其它视图,内在固有尺寸甚至更加复杂。 举个例子, 一个空的图像视图没有一个内在固有尺寸。但是一旦你添加了一个图片,它的内在固有尺寸就被设置为图片的尺寸。

A text view’s intrinsic content size varies depending on the content, on whether or not it has scrolling enabled, and on the other constraints applied to the view. For example, with scrolling enabled, the view does not have an intrinsic content size. With scrolling disabled, by default the view’s intrinsic content size is calculated based on the size of the text without any line wrapping. For example, if there are no returns in the text, it calculates the height and width needed to layout the content as a single line of text. If you add constraints to specify the view’s width, the intrinsic content size defines the height required to display the text given its width.

一个文本视图的内在固有尺寸根据它的内容发生改变,根据它是否开启了滚动,还根据应用于该视图的其它约束。 比如,如果开启了滚动,则视图没有内在固有尺寸。 如果没有开启滚动,默认情况下,视图的内在固有尺寸根据文本的尺寸来计算,不带任何换行符。 比如,如果文本中没有返回符(returns), 它计算所需的高度和宽度来布置内容一行显示。如果你添加了一个约束来指定视图的宽度, 内在内容尺寸定义需要的高度来显示它的文本,而该文本的宽度已经被指定。

Auto Layout represents a view’s intrinsic content size using a pair of constraints for each dimension. The content hugging pulls the view inward so that it fits snugly around the content. The compression resistance pushes the view outward so that it does not clip the content.

自动布局用给每个尺寸指定一对约束来表示一个视图的内在内容尺寸。 content hugging 把视图拉紧,是它紧紧围绕在内容周围。 compression resistance 把视图往外推,这样它就不会把内容剪掉。

image: ../Art/intrinsic_content_size_2x.png

These constraints are defined using the inequalities shown in Listing 3-5. Here, the IntrinsicHeight andIntrinsicWidth constants represent the height and width values from the view’s intrinsic content size.

这些约束可以用列表3-5中的不等式表示。 这里,IntrinsicHeight 和 IntrinsicWidth常量表示从视图的内在内容尺寸中获得的高度和宽度。

Listing 3-5Compression-Resistance and Content-Hugging equations

  1. // Compression Resistance
  2. View.height >= 0.0 * NotAnAttribute + IntrinsicHeight
  3. View.width >= 0.0 * NotAnAttribute + IntrinsicWidth
  4. // Content Hugging
  5. View.height <= 0.0 * NotAnAttribute + IntrinsicHeight
  6. View.width <= 0.0 * NotAnAttribute + IntrinsicWidth

Each of these constraints can have its own priority. By default, views use a 250 priority for their content hugging, and a 750 priority for their compression resistance. Therefore, it’s easier to stretch a view than it is to shrink it. For most controls, this is the desired behavior. For example, you can safely stretch a button larger than its intrinsic content size; however, if you shrink it, its content may become clipped. Note that Interface Builder may occasionally modify these priorities to help prevent ties. For more information, see Setting Content-Hugging and Compression-Resistance Priorities.

这里的每个约束都可以有自己的优先值。 默认情况下,使用的content hugging 使用250优先值, compression resistance 使用750优先值。 因此,拉长(stretch)一个视图比压缩(shrink)一个视图更容易。对于大多数控件来说,这是所期望的行为。 比如,你可以安全地把一个按钮拉得比它的内在内容尺寸更大;但是,如果你压缩它,它的内容就有可能被剪掉。请注意,Interface Builder可能会随意地改变这些优先值以避免被绑定。 更多信息,请看Setting Content-Hugging and Compression-Resistance Priorities.

Whenever possible, use the view’s intrinsic content size in your layout. It lets your layout dynamically adapt as the view’s content changes. It also reduces the number of constraints you need to create a nonambiguous, nonconflicting layout, but you will need to manage the view’s content-hugging and compression-resistance (CHCR) priorities. Here are some guidelines for handling intrinsic content sizes:

任何时候只要有可能,就可以在你的布局里使用视图的内在内容尺寸。 它让你的布局可以动态地适合新的视图内容。 它还能减少创建一个清晰不冲突布局所需的约束,但是你将需要管理视图的content-hugging 和 compression-resistance(CHCR)优先值。 以下是一些处理内在内容尺寸的建议:

  • When stretching a series of views to fill a space, if all the views have an identical content-hugging priority, the layout is ambiguous. Auto Layout doesn’t know which view should be stretched.

     当你需要拉伸一系列视图来填满一个空白时,如果所有的视图都有一个相同的content-hugging 优先值,布局就是模棱两可的。自动布局不知道该拉伸哪个视图。

    A common example is a label and text field pair. Typically, you want the text field to stretch to fill the extra space while the label remains at its intrinsic content size. To ensure this, make sure the text field’s horizontal content-hugging priority is lower than the label’s.

     一个常见的示例是一个标签和一个文本区域。 通常,你想要文本区拉伸以填满额外的空白,而标签可以保持它的内在内容尺寸。 为了确保这个,请确保文本区的水平content-hugging 优先值比标签的水平content-hugging 优先值低。

    In fact, this example is so common that Interface Builder automatically handles it for you, setting the content-hugging priority for all labels to 251. If you are programmatically creating the layout, you need to modify the content-hugging priority yourself.

     事实上,该示例太普遍了,以至于Interface Builder自动为你这样处理了,它为所有的标签content-hugging 优先值都设置为251. 如果你是通过程序创建的布局,你需要自己动手修改content-hugging 优先值。

  • Odd and unexpected layouts often occur when views with invisible backgrounds (like buttons or labels) are accidentally stretched beyond their intrinsic content size. The actual problem may not be obvious, because the text simply appears in the wrong location. To prevent unwanted stretching, increase the content-hugging priority.

     当带有不可见背景(像按钮或者标签等)的视图不小心被拉伸经常会产生奇怪的不可预期的布局。 真正的问题可能并不明显,因为文本简单地显示在了错误的位置。要想避免不想要的拉伸,增加content-hugging 优先值。

  • Baseline constraints work only with views that are at their intrinsic content height. If a view is vertically stretched or compressed, the baseline constraints no longer align properly.

     下划线约束只应用于视图的内在内容高度。 如果一个视图被纵向的拉伸或压缩,下划线约束就不能被正确对齐。

  • Some views, like switches, should always be displayed at their intrinsic content size. Increase their CHCR priorities as needed to prevent stretching or compressing.

     一些视图,像开关等,应该总是以它们的内在内容尺寸显示。 根据需要可以增加它们的CHCR优先值来避免被拉伸或压缩。

  • Avoid giving views required CHCR priorities. It’s usually better for a view to be the wrong size than for it to accidentally create a conflict. If a view should always be its intrinsic content size, consider using a very high priority (999) instead. This approach generally keeps the view from being stretched or compressed but still

    provides an emergency pressure valve, just in case your view is displayed in an environment that is bigger or smaller than you expected.

     避免给视图设置必须的CHCR优先值。通常,即使是把一个视图的尺寸设置错误,也比不小心创建了一个冲突(conflict)好。如果一个视图需要总是保持它的内在内容尺寸不能改变,考虑使用一个很高的优先值(999)。该方法通常让视图保持不被拉伸或压缩,但是它还是有一个例外, 那就是当你的视图显示在一个比你预期大的或小的环境时。

Intrinsic Content Size Versus Fitting Size

内在内容尺寸 VS 合适的尺寸

The intrinsic content size acts as an input to Auto Layout. When a view has an intrinsic content size, the system generates constraints to represent that size and the constraints are used to calculate the layout.

内在内容尺寸就像是自动布局的一个输入。 当一个视图有一个内在内容尺寸时,系统生成各种约束来表示那个尺寸,同时这些约束用于计算布局。

The fitting size, on the other hand, is an output from the Auto Layout engine. It is the size calculated for a view based on the view’s constraints. If the view lays out its subviews using Auto Layout, then the system may be able to calculate a fitting size for the view based on its content.

另外,合适的尺寸是自动布局引擎的一个输出。 它的尺寸是视图根据视图的约束计算出来的。如果视图使用自动布局来布局它的子视图,系统或许可以根据它的内容给视图计算出适合它的尺寸。

The stack view is a good example. Barring any other constraints, the system calculates the stack view’s size based on its content and attributes. In many ways, the stack view acts as if it had an intrinsic content size: You can create a valid layout using only a single vertical and a single horizontal constraint to define its position. But its size is calculated by Auto Layout—it is not an input into Auto Layout. Setting the stack view’s CHCR priorities has no effect, because the stack view does not have an intrinsic content size.

堆栈视图是一个很好的示例。除非有其它任何约束,系统根据它的内容和各种属性计算出堆栈视图的尺寸。 从很多方面来说, 堆栈视图就好像有一个内在内容尺寸;你也可以只使用一个垂直和一个水平方向的约束来定位它的位置就可以创建一个有效的布局。 但是它的尺寸是由自动布局计算的---它不是自动布局的一个输入。 设置堆栈视图的CHCR优先值没有任何效果,因为堆栈视图没有一个内在内容尺寸。

If you need to adjust the stack view’s fitting size relative to items outside the stack view, either create explicit constraints to capture those relationships or modify the CHCR priorities of the stack’s contents relative to the items outside the stack.

如果你需要让堆栈视图的合适尺寸跟堆栈视图外面的对象相关联,你可以创建明确的约束来捕捉那些关系或者修改跟堆栈外面的对象相关联的内容的CHCR优先值。

Interpreting Values

自动布局各种值的解释

Values in Auto Layout are always in points. However, the exact meaning of these measurements can vary depending on the attributes involved and the view’s layout direction.

自动布局里的各种值总是以点的方式表示。 但是这些数据的实际意义根据涉及的各种属性以及视图的布局方向会发生变化。

 

Auto Layout Attributes

Value

Notes

image: ../Art/ALGuide_Height.pdfHeight

image: ../Art/ALGuide_Width.pdfWidth

The size of the view.

视图的尺寸

These attributes can be assigned constant values or combined with other Height and Width attributes. These values cannot be negative.

这些属性可以是常量或是常量和别的高度/宽度属性的组合。 这些值不能是负值。

image: ../Art/ALGuide_TopToSuper.pdfTop

image: ../Art/ALGuide_BottomToSuper.pdfBottom

image: ../Art/ALGuide_AlignMiddle.pdfBaseline

The values increase as you move down the screen.

当你在屏幕上向下移动时,这些值会增加(坐标原点在屏幕左上角)。

These attributes can be combined only with Center Y, Top, Bottom, and Baseline attributes.

这些属性只能由Center Y, Top, Bottom 以及Baseline 属性组成。

image: ../Art/ALGuide_LeftToSuper.pdfLeading

image: ../Art/ALGuide_RightToSuper.pdfTrailing

The values increase as you move towards the trailing edge. For a left-to-right layout directions, the values increase as you move to the right. For a right-to-left layout direction, the values increase as you move left.

当你沿着尾缘(trailing edge)移动时,这些值增加。 从左到右布局方向,当你向右移动时,这些值增加。 从右到左布局方向, 当你向左移动时,这些值增加。

These attributes can be combined only with Leading, Trailing, or Center X attributes.

这些属性只能由Leading, Trailing 或者 Center X属性组成。

image: ../Art/ALGuide_LeftToSuper.pdfLeft

image: ../Art/ALGuide_RightToSuper.pdfRight

The values increase as you move to the right.

当你向右移动时,这些值会增加。

These attributes can be combined only with Left, Right, and Center X attributes.

这些属性只能由Left, Right, 和Center X属性组成。

Avoid using Left and Right attributes. Use Leading and Trailing instead. This allows the layout to adapt to the view’s reading direction.

不使用Left 和 Right属性。 使用Leading 和 Trailing 属性代替。 这样就能让布局适配视图的阅读方向。

By default the reading direction is determined based on the current language set by the user. However, you can override this where necessary. In iOS, set the superview’s semanticContentAttribute property to specify whether the content’s layout should be flipped when switching between left-to-right and right-to-left languages. In OS X set the superview’s userInterfaceLayoutDirection property.

默认情况下,阅读方向是由用户设置的当前语言来决定的。 但是你可以在必要时使它无效。 在iOS,当切换从左到右 还是从右到做语言环境时,设置父视图的semanticContentAttribute 特性来制定内容的布局是否需要被翻转。在 OS X设置父视图的userInterfaceLayoutDirection特性。

image: ../Art/ALGuide_AlignCenter.pdfCenter X

image: ../Art/ALGuide_AlignMiddle.pdfCenter Y

The interpretation is based on the other attribute in the equation.

根据方程式中的其它属性来解释。

Center X can be combined with Center X, Leading, Trailing, Right, and Left attributes.

Center X 可以由Center X, Leading, Trailing, Right, 和Left属性组成。

Center Y can be combined with Center Y, Top, Bottom, and Baseline attributes.

Center Y 可以由 Center Y, Top, Bottom, 和 Baseline 属性组成。

posted on 2015-12-29 21:02  cainiaozhang  阅读(701)  评论(1编辑  收藏  举报