前言:
这一篇是翻译自动布局指南系列第二篇,书接上文,讲的是自动布局的概念
Auto Layout Concepts(自动布局概念)
The fundamental building block in Auto Layout is the constraint. Constraints express rules for the layout of elements in your interface; for example, you can create a constraint that specifies an element’s width, or its horizontal distance from another element. You add and remove constraints, or change the properties of constraints, to affect the layout of your interface.
When calculating the runtime positions of elements in a user interface, the Auto Layout system considers all constraints at the same time, and sets positions in such a way that best satisfies all of the constraints.
Constraint Basics(约束基础)
You can think of a constraint as a mathematical representation of a human-expressable statement. If you’re defining the position of a button, for example, you might want to say “the left edge should be 20 points from the left edge of its containing view.” More formally, this translates to button.left = (container.left + 20)
, which in turn is an expression of the form y = m*x + b
, where:
-
y
andx
are attributes of views. -
m
andb
are floating point values.
- x 和y 是视图的属性
- m和b 是浮点型数值
An attribute is one of left
, right
, top
, bottom
, leading
, trailing
, width
, height
, centerX
, centerY
, and baseline
.
The attributes leading
and trailing
are the same as left
and right
for left-to-right languages such as English, but in a right-to-left environment such as Hebrew or Arabic, leading
and trailing
are the same as right
and left
. When you create constraints, leading
and trailing
are the default values. You should usually use leading
and trailing
to make sure your interface is laid out appropriately in all languages, unless you’re making constraints that should remain the same regardless of language (such as the order of master and detail panes in a split view).
属性为如下之一:左,右,上,下,领先,落后,宽,高,中心X,中心Y,基线。
领先(leading)和落后(trailing)属性就像左和右对于左右语言像英语,但是对于右左语境的语言像希伯来语和阿拉伯语,(leading)领先和落后(trailing)就像右左一样。当你创建约束的时候,领先和落后是默认值。你应该总是使用leading和trailing来保证适合所有的语言,除非你做这样的限制:所有语言保持一致(就像……不知道怎么翻译)。
(PS:这一段说了约束的几个属性)
Constraints can have other properties set:
-
Constant value. The physical size or offset, in points, of the constraint.
-
Relation. Auto Layout supports more than just constant values for view attributes; you can use relations and inequalities such as greater-than-or-equal to specify, for example, that a view’s
width >= 20
, or even thattextview.leading >= (superview.leading + 20)
. -
Priority level. Constraints have a priority level. Constraints with higher priority levels are satisfied before constraints with lower priority levels. The default priority level is required (
NSLayoutPriorityRequired
), which means that the constraint must be satisfied exactly. The layout system gets as close as it can to satisfying an optional constraint, even if it cannot completely achieve it.Priority levels allow you to express useful conditional behavior. For example, they are used to express that some controls should always be sized to fit their contents, unless something more important should take precedence. For more information about priority levels, see
NSLayoutPriority
.
常量。物理大小或相对原点偏移量,在约束(constraint)的points里面
关系。自动布局不仅仅支持视图属性的常量;你可以使用关系和不等式比如View的width>=20,或者 textview.leading>=(superview.leading+20)
优先级。约束有优先级。具有高优先级的约束比低优先级的约束先实现。默认的优先级是必要级(NSLayoutPriorityRequired),这意味着约束必须被完全满足(完全实现)。如果一个约束的优先级是选择完成,那么布局系统会尽量完成的接近这个约束,即使这个约束不能被完全实现。
优先级的存在允许你表达有用的约束行为。比如,他们常用来表达某些控件应该适应内容的大小,除非更重要的事情要被优先做。更多关于优先级的信息,请看《NSLayoutPriority》
(PS:约束的优先级,关系)
Constraints are cumulative, and do not override each other. If you have an existing constraint, setting another constraint of the same type does not override the previous one. For example, setting a second width constraint for a view does not remove or alter the first width constraint—you need to remove the first constraint manually.
Constraints can, with some restrictions, cross the view hierarchy. In the Mail app in OS X, for example, by default the Delete button in the toolbar lines up with the message table; in Desktop Preferences, the checkboxes at the bottom of the window align with the split view pane they operate on.
You cannot set a constraint to cross the view hierarchy if the hierarchy includes a view that sets the frames of subviews manually in a custom implementation for the layoutSubviews
method on UIView
(or the layout
method on NSView
). It’s also not possible to cross any views that have a bounds transform (such as a scroll view). You can think of such views as barriers—there’s an inside world and an outside world, but the inside cannot be connected to the outside by constraints.
Intrinsic Content Size (内在内容的大小)
Leaf-level views such as buttons typically know more about what size they should be than does the code that is positioning them. This is communicated through the intrinsic content size, which tells the layout system that a view contains some content that it doesn’t natively understand, and indicates how large that content is, intrinsically.
For elements such as text labels, you should typically set the element to be its intrinsic size (select Editor > Size To Fit Content). This means that the element will grow and shrink appropriately with different content for different languages.
Application Architecture(应用程序中架构)
The Auto Layout architecture distributes responsibility for layout between controllers and views. Rather than writing an omniscient controller that calculates where views need to go for a given geometry, views become more self-organizing. This approach reduces the complexity of controller logic, and makes it easier to redesign views without requiring corresponding changes to the layout code.
You may still want a controller object that adds, removes, or adjusts constraints at runtime. To learn more about managing constraints in code, read Working with Auto Layout Programmatically.
The Role of the Controller(控制器的角色)
Although a view specifies its intrinsic content size, the user of the view says how important it is. For example, by default, a button:
-
Strongly wants to hug its content in the vertical direction (buttons really ought to be their natural height)
-
Weakly hugs its content horizontally (extra side padding between the title and the edge of the bezel is acceptable)
-
Strongly resists compressing or clipping content in both directions
- 垂直方向强限制:(会努力保持button自己的高度)
- 水平方向上弱限制(可以根据标题的填充和边界来拉伸水平的长度)
- 在两个(水平垂直)方向上绝对不允许压缩和裁剪
In a user interface containing two buttons next to each other, for example, it’s up to the controller to decide how the buttons should grow if there’s extra room. Should just one of the buttons grow? Should both grow equally? Or maybe proportionally to each other? If there isn’t enough room to fit both buttons without compressing or clipping the content, should one button be truncated first? Or both equally? And so on.
You set the hugging and compression priorities for a UIView
instance using setContentHuggingPriority:forAxis:
and setContentCompressionResistancePriority:forAxis:
(for NSView
, you use setContentHuggingPriority:forOrientation:
and setContentCompressionResistancePriority:forAxis:
). By default, all UIKit- and AppKit-supplied views have a value of eitherNSLayoutPriorityDefaultHigh
or NSLayoutPriorityDefaultLow
.
setContentHuggingPriority:forAxis:
and setContentCompressionResistancePriority:forAxis:
(NSView 有另外两个方法:)在默认的情况下,所有UIKit 和AppKit 支持的view都会有这两个属性:NSLayoutPriorityDefaultHigh
or NSLayoutPriorityDefaultLow
.