Auto Layout Guide----(三)-----Anatomy of a Constraint
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.
视图层次中的布局是以一系列的线性方程来定义的。 每个约束表示一个方程。 你的目标就是声明一系列的方程,并且每个方程有且仅有一个可能的解决方法。 以下是一个方程:
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)属性。
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
// Setting a constant height
View.height = 0.0 * NotAnAttribute + 40.0
// Setting a fixed distance between two buttons
Button_2.leading = 1.0 * Button_1.trailing + 8.0
// Aligning the leading edge of two buttons
Button_1.leading = 1.0 * Button_2.leading + 0.0
// Give two buttons the same width
Button_1.width = 1.0 * Button_2.width + 0.0
// Center a view in its superview
View.centerX = 1.0 * Superview.centerX + 0.0
View.centerY = 1.0 * Superview.centerY + 0.0
// Give a view a constant aspect ratio
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
// Setting a fixed distance between two buttons
Button_1.trailing = 1.0 * Button_2.leading - 8.0
// Aligning the leading edge of two buttons
Button_2.leading = 1.0 * Button_1.leading + 0.0
// Give two buttons the same width
Button_2.width = 1.0 * Button.width + 0.0
// Center a view in its superview
Superview.centerX = 1.0 * View.centerX + 0.0
Superview.centerY = 1.0 * View.centerY + 0.0
// Give a view a constant aspect ratio
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:
你将发现自动布局常常提供不同方法来解决同一个问题。 最好,你应该选择一中最能描述你的意向的解决方法。但是,不同的开发者毫不迟疑地选择不同的最好解决方法。 在这里,我要说选择你一贯的解决方法比选择正确的更好。 如果你选择一种方法并一直使用它,从长期来看你将减少很多问题。 比如, 请看以下规则:
Whole number multipliers are favored over fractional multipliers.
整数乘数比小数乘数好。
Positive constants are favored over negative constants.
正常量比负常量好。
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)设置两个约束(不计算父视图)。但是,当你需要选择该使用什么约束时,你有大范围的选择。 比如,以下三个布局都产生清晰的,满足的布局(仅显示水平约束):
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:
以下是视图的垂直和水平方向的图示:
So what should these constraints look like? The following illustration shows one straightforward solution:
那么这些约束该怎么设置呢?下图演示了一种简单的解决方法:
The above solution uses the following constraints:
以上方法使用了以下约束:
// Vertical Constraints
Red.top = 1.0 * Superview.top + 20.0
Superview.bottom = 1.0 * Red.bottom + 20.0
Blue.top = 1.0 * Superview.top + 20.0
Superview.bottom = 1.0 * Blue.bottom + 20.0
// Horizontal Constraints
Red.leading = 1.0 * Superview.leading + 20.0
Blue.leading = 1.0 * Red.trailing + 8.0
Superview.trailing = 1.0 * Blue.trailing + 20.0
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:
但是,这仍然不是唯一可能的解决办法。以下是一个效果的方法:
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.
除了为红蓝视图分别指定相对于父视图的上下边界,你可以让蓝视图的上下边界跟红视图相对齐。 以下是这些约束的方程式:
// Vertical Constraints
Red.top = 1.0 * Superview.top + 20.0
Superview.bottom = 1.0 * Red.bottom + 20.0
Red.top = 1.0 * Blue.top + 0.0
Red.bottom = 1.0 * Blue.bottom + 0.0
//Horizontal Constraints
Red.leading = 1.0 * Superview.leading + 20.0
Blue.leading = 1.0 * Red.trailing + 8.0
Superview.trailing = 1.0 * Blue.trailing + 20.0
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
// Setting the minimum width
View.width >= 0.0 * NotAnAttribute + 40.0
// Setting the maximum width
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
// A single equal relationship
Blue.leading = 1.0 * Red.trailing + 8.0
// Can be replaced with two inequality relationships
Blue.leading >= 1.0 * Red.trailing + 8.0
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列出了其中一些视图:
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 把视图往外推,这样它就不会把内容剪掉。
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
// Compression Resistance
View.height >= 0.0 * NotAnAttribute + IntrinsicHeight
View.width >= 0.0 * NotAnAttribute + IntrinsicWidth
// Content Hugging
View.height <= 0.0 * NotAnAttribute + IntrinsicHeight
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 |
---|---|---|
Height Width |
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. 这些属性可以是常量或是常量和别的高度/宽度属性的组合。 这些值不能是负值。 |
Top Bottom Baseline |
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 属性组成。 |
Leading Trailing |
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属性组成。 |
Left Right |
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 默认情况下,阅读方向是由用户设置的当前语言来决定的。 但是你可以在必要时使它无效。 在iOS,当切换从左到右 还是从右到做语言环境时,设置父视图的 |
Center X Center 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 属性组成。 |
Auto Layout Without Constraints
Working with Constraints in Interface Builder
Auto Layout Guide----(三)-----Anatomy of a Constraint的更多相关文章
- 【转】使用 Auto Layout 的典型痛点和技巧
layoutIfNeeded()强制立刻更新布局 原文网址:http://www.jianshu.com/p/0f031606e5f2 官方文档:Auto Layout Guide 加上去年WWDC上 ...
- 深入理解Auto Layout 第一弹
本文转载至 http://zhangbuhuai.com/2015/07/16/beginning-auto-layout-part-1/ By 张不坏 2015-07-16 更新日期:2015-07 ...
- iOS 开发实践之 Auto Layout
原:http://xuexuefeng.com/autolayout/?utm_source=tuicool 本文是博主 iOS 开发实践系列中的一篇,主要讲述 iOS 中 Auto Layout(自 ...
- iOS开发之Auto Layout入门(转)
随着iPhone6与iOS8的临近,适配的问题讲更加复杂,最近学习了一下Auto Layout的使用,与大家分享. 什么是Auto Layout? Auto Layout是iOS6发布后引入的一个全新 ...
- iOS屏幕适配方案-Auto Layout
市场上的android手机五花八门.各种尺寸的屏幕让android程序员们比較头疼. 也有一些大神写了一些博客提出了自己的观点.iOS貌似也迎来了大屏6+,因此屏幕适配的问题也是有滴,因此苹果也有自己 ...
- Auto Layout Guide----(一)-----Understanding Auto Layout
Understanding Auto Layout 理解自动布局 Auto Layout dynamically calculates the size and position of all the ...
- iOS 8 Auto Layout界面自动布局系列2-使用Xcode的Interface Builder添加布局约束
http://blog.csdn.net/pucker/article/details/41843511 上一篇文章<iOS 8界面自动布局系列-1>简要介绍了iOS界面布局方式的前世今生 ...
- 【转 iOS 8 Auto Layout界面自动布局系列2-使用Xcode的Interface Builder添加布局约束
原文网址:http://blog.csdn.net/pucker/article/details/41843511 上一篇文章<iOS 8界面自动布局系列-1>简要介绍了iOS界面布局方式 ...
- iOS6 自动布局 入门–Auto Layout(转)
iOS6 自动布局 入门–Auto Layout(转) 标签: 杂谈 目前为止,即使你的界面设计是在合理的复杂度内,你也必须要为之写许多代码来适应变化的布局.现在我相信你会很高兴听到这种情况将不会 ...
随机推荐
- Trie树,又称单词查找树、字典
在百度或淘宝搜索时,每输入字符都会出现搜索建议,比如输入“北京”,搜索框下面会以北京为前缀,展示“北京爱情故事”.“北京公交”.“北京医院”等等搜索词.实现这类技术后台所采用的数据结构是什么?[中国某 ...
- TP框架---thinkphp模型
1.获取系统常量信息的方法:在控制器DengLuController里面下写入下面的方法,然后调用该方法. public function test() { //echo "这是测试的&qu ...
- 【BZOJ4569】[Scoi2016]萌萌哒 倍增+并查集
[BZOJ4569][Scoi2016]萌萌哒 Description 一个长度为n的大数,用S1S2S3...Sn表示,其中Si表示数的第i位,S1是数的最高位,告诉你一些限制条件,每个条件表示为四 ...
- word操作
- framemarker的使用
1 什么是framemarker framemarker是网页模版和数据模型的结合体.装载网页的时候,framemarker自动从数据模型中提取数据并生成html页面. 2 framemarker怎么 ...
- Java中的迭代迭代器Iterator与枚举器Enumeration
Iterator 和 Enumeration区别 Iterator 和 Eumberation都是Collection集合的遍历接口,我们先看下他们的源码接口 package java.util; p ...
- 调用jersey发布的接口webservice,通过HttpPost传递文件
项目媒体文件之前都是上传到七牛云处理,现在客户为了安全和私密性,准备将移动端拍摄的图片和视频传递到文件服务器,所以就想办法能不能在服务器端发布一个WebService,供移动端调用.刚好之前做的接口都 ...
- PYTHON 爬虫笔记六:PyQuery库基础用法
知识点一:PyQuery库详解及其基本使用 初始化 字符串初始化 html = ''' <div> <ul> <li class="item-0"&g ...
- Hadoop- MapReduce分布式计算框架原理
分布式计算: 原则:移动计算而尽可能减少移动数据(减少网络开销) 分布式计算其实就是将单台机器上的计算拓展到多台机器上并行计算. MapReduce是一种编程模型.Hadoop MapReduce采用 ...
- matlab之sortrows()函数
sortrows()函数的格式: sortrows(A,column) A是一个矩阵,如果没有第二个参数column,则默认按照第一列升序排列,如果遇到重复数字,则按照第二列升序排列,依次类推... ...