Working with Constraints in Interface Builder
The easiest way to add, edit, or remove constraints is to use the visual layout tools in Interface Builder. Creating a constraint is as simple as Control-dragging between two views, or to add multiple constraints at once, you simply use the various pop-up windows.
在Interface Builder里用约束来工作
最简单的方法去增加,编辑和删除约束项就是使用Interface Builder的可视化的布局工具。创建一个约束就和按住control键拉两个视图一起一样简单,或者一次增加多个约束项,你简单地使用不同的弹出窗口。Adding Constraints
When you drag out an element from the Object Library and drop it on the Interface Builder canvas, it starts out unconstrained to make it easy to prototype your interface by dragging elements around. If you build and run without adding any constraints to an element, you’ll find that Interface Builder fixes the element’s width and height, and pins its position relative to the top left corner of the superview; this means that resizing the window doesn’t move or resize the elements. To make your interface react correctly to changes in size or orientation, you need to start adding constraints.
Important: Although Xcode does not generate a warning or an error when you build a user interface that does not have appropriate constraints, you should not ship your application in such a state.
There are several ways to add constraints depending on the level of precision you want and the number of constraints you want to add at a time.
重要: 尽管Xcode并没有生成警告或者错误当你在创建一个用户界面的时候并没有创建一个合适的约束,你不能将你的应用置于那种情况。
这里有几种方法去添加约束项,取决于你想要的精确的水平和你每次想要增加的约束项的数量。
Adding Constraints with Control-Drag
The fastest way to add a constraint is by holding down the Control key and dragging from a view on the canvas, much like the way you create links to outlets or actions. This Control-drag method is a quick, precise tool for creating a single constraint when you know exactly what type of constraint you want and where you want it.
You can Control-drag from an element to itself, to its container, or to another element. Depending on what you drag to and which direction you drag in, Auto Layout limits the possibilities of constraints appropriately. For example, if you drag horizontally to the right from an element to its container, you have the options to pin the element’s trailing space or to center it vertically in the container.
按住control键拉动来添加约束项
最快的方法去添加一个约束项是在画布中按住control键并且从一个视图拉动,就像是你用产生线的方法去创建outlets和actions。这种按住control键去创建的方法很快,是一种精确的工具当你准确地知道当你想要添加什么约束类型的时候。你可以通过control键添加约束给它本身,它的容器类或者其他的元素。取决于你拉什么和哪个方法你拉,自动布局合适地限制了约束的可能性。例如,如果你水平地将这个元素从它的容器类向右拉,你将会有选项去pin这个元素在它的容器的的trailing space或者垂直的中心位置。
To select multiple constraints at a time from the Control-drag menu, hold down the Command or Shift key
一次选择多个约束项的话同时按住Command键和Shift键
Adding Constraints with Align and Pin Menus
You can also add constraints using the Auto Layout menu, which resides on the Interface Builder canvas.
用对齐和pin菜单去增加约束项
你也可以用自动布局菜单去增加约束项,这重新调整了Interface Builder画布的大小。
In addition to adding constraints for alignment or spacing, you can also use this menu to resolve layout issues, and determine constraint resizing behavior.
另外去增加alignment和spacing的约束项,你可以用这个菜单去解决布局问题,和确定约束重新调整大小的行为。
-
Align. Create alignment constraints, such as centering a view in its container, or aligning the left edges of two views.
-
Pin. Create spacing constraints, such as defining the height of a view, or specifying its horizontal distance from another view.
-
Issues. Resolve layout issues by adding or resetting constraints based on suggestions (see Resolving Auto Layout Issues).
-
Resizing. Specify how resizing affects constraints .
-
对齐. 创建一个对齐约束项,例如将一个视图置于它的容器的中心,或者对齐两个视图的左边缘。
-
Pin. 建一个空间约束,例如定义一个视图的高度,或者指定它与其他视图的水平距离。
-
Issues. 通过增加或者重新设置基于建议的约束解决布局问题 (详情可看 Resolving Auto Layout Issues).
-
重新调整大小. 确定重新调整对约束的影响。
Constraint options that require multiple elements are disabled if you have only a single element selected.
约束选项要求多个元素不被工作如果你仅仅只有单个元素被选择。
Adding Missing or Suggested Constraints
Use the Issues menu to add constraints if you need a starting point for your layout, or if you need to make a lot of changes quickly.
If you need to add a large set of constraints to describe your interface layout and you don’t want to add constraints one at a time, choose Issues > Add Missing Constraints to add a nonambiguous set of constraints. This command infers constraints based on where things are laid out.
If you need to revert to a set of constraints without errors, or you just want to start over, choose Issues > Reset to Suggested Constraints to remove erroneous constraints and add a nonambiguous set of constraints. This is equivalent to Clear Constraints followed by Add Missing Constraints.
增加缺失或者被建议的约束项
如果你需要不发生错误地还原到一组约束,或者你仅仅是想重新开始,选择Issues>Reset去选择被建议的约束项去删除可能发生错误的约束项并且增加清晰的约束集。这个相当于清楚约束项其次是增加缺失的约束项。
Editing Constraints
You can change the constant, relation, and priority of a constraint. You can edit these properties either by double-clicking the constraint on the canvas and editing the value, or by selecting the constraint and using the Attributes inspector. You cannot, however, change the type of a constraint (for example, you can’t change a width constraint into a height constraint).
编辑 约束
你可以改变约束,它的关系,和它的优先级,你可以编辑这些属性通过在画布中双击和编辑它的值,或者通过选择约束并且使用Attributes inspecotr,你不能改变约束的类型(例如,你不能将宽度的约束改变成高度的约束)
Deleting Constraints
Delete any constraint at any time by selecting it on the canvas or in the outline view and pressing the Delete key.
删除 约束项
删除任意的约束在任时间通过选择它在画布上并且在线外的视图并且按下删除键。
Working with Auto Layout Programmatically
Even though Interface Builder provides a convenient visual interface for working with Auto Layout, you can also create, add, remove, and adjust constraints through code. If you add or remove views at runtime, for example, you’ll need to add constraints programmatically to ensure that your interface responds correctly to changes in size or orientation.
以编程的方式用自动布局工作
提供了一个方便地可视化的界面去用Auto Layout工作,你也可以创建,添加和调整约束项通过代码。如果你在运行的时候添加和删除了视图,例如,你将需要以编程的方式去添加一个约束来保证你的界面会合适对大小和方向的改变作出反应。Creating Constraints Programmatically
You represent constraints using instances of NSLayoutConstraint
.To create constraints, you typically use constraintsWithVisualFormat:options:metrics:views:
.
The first argument to this method, a visual format string, provides a visual representation of the layout you want to describe. Thisvisual format language is designed to be as readable as possible; a view is represented in square brackets, and a connection between views is represented using a hyphen (or two hyphens separated by a number to represent the number of points apart the views should be). For more examples and to learn the grammar for the visual format language, see Visual Format Language.
As an example, you might represent the constraint between two buttons:
以编程的方式去创建约束
你用 NSLayoutConstraint
. 的实例去代表约束, 为了创建约束, 你通常使用方法 constraintsWithVisualFormat:options:metrics:views:
.
这个方法的第一个参数, 一个时可视化格式字符串,提供了一个你想去描述的可视化的布局的代表,这里的可视化格式语言是被设计成尽可能的更易读; 一个视图代表一个方括号,而视图间的连接的代表则采用一个连字符号(或者两个连字符号被一个数字分开去代表视图应该分开的数字) 为了更多的例子和了解可视化语言的语法,可以看到 Visual Format Language.
作为一个例子,你表示这两个按钮的约束:
using the following visual format string:
[button1]-12-[button2] |
A single hyphen denotes the standard Aqua space, so you can also represent the relationship like this:
[button1]-[button2] |
The names of the views come from the views
dictionary—the keys are the names you use in the format string, and the values are the corresponding view objects. As a convenience, NSDictionaryOfVariableBindings
creates a dictionary where the keys are the same as the corresponding value’s variable name. The code to create the constraints becomes:
NSDictionary *viewsDictionary = |
NSDictionaryOfVariableBindings(self.button1, self.button2); |
NSArray *constraints = |
[NSLayoutConstraint constraintsWithVisualFormat:@"[button1]-[button2]" |
options:0 metrics:nil views:viewsDictionary]; |
The visual format language prefers good visualization over completeness of expressibility. Although most of the constraints that are useful in real user interfaces can be expressed using the language, some cannot. One useful constraint that cannot be expressed is a fixed aspect ratio (for example, imageView.width = 2 * imageView.height
). To create such a constraint, you can useconstraintWithItem:attribute:relatedBy:toItem:attribute:multiplier:constant:
.
As an example, you could also use this method to create the earlier [button1]-[button2]
constraint:
[NSLayoutConstraint constraintWithItem:self.button1 attribute:NSLayoutAttributeRight |
relatedBy:NSLayoutRelationEqual toItem:self.button2 |
attribute:NSLayoutAttributeLeft multiplier:1.0 constant:-12.0]; |
使用下面的可视化字符串:
[button1]-12-[button2] |
单个连字符表示标准的方括号,你也可以这样去表示:
[button1]-[button2] |
这个视图的名字来自views字典参数-键值是你所使用的标准字符串的名字,而value值就是相应的视图对象。为了方便,NSDictionaryOfVariableBindings创建了一个字典,这个字典的键值和它对应值的变量名相同。创建constraints的代码变成如下:
NSDictionary *viewsDictionary = |
NSDictionaryOfVariableBindings(self.button1, self.button2); |
NSArray *constraints = |
[NSLayoutConstraint constraintsWithVisualFormat:@"[button1]-[button2]" |
options:0 metrics:nil views:viewsDictionary]; |
可视化格式语言比之于完整的表达格式它更偏向于好的可读化。尽管大多数在用户界面很有用的约束能够被表达通过语言,然而,有些不能。其中一个有用的约束不能被表达成固定的横纵比率(例如,imageView.width = 2*imageView.height)为了创建这样一个约束,你可以使用:constraintWithItem:attribute:relatedBy:toItem:attribute:multiplier:constant:。
例如,你可以使用这个方法去创建前面的[button1]-[button2]约束:
[NSLayoutConstraint constraintWithItem:self.button1 attribute:NSLayoutAttributeRight |
relatedBy:NSLayoutRelationEqual toItem:self.button2 |
attribute:NSLayoutAttributeLeft multiplier:1.0 constant:-12.0]; |
Installing Constraints
To make a constraint active, you must add it to a view. The view that holds the constraint must be an ancestor of the views the constraint involves, and should usually be the closest common ancestor. (This is in the existing NSView
API sense of the word ancestor, where a view is an ancestor of itself.) The constraint is interpreted in the coordinate system of that view.
Suppose you install [zoomableView1]-80-[zoomableView2]
on the common ancestor of zoomableView1
and zoomableView2
.
安装 限制
为了激活约束,你必须把它加到视图上。这个拥有约束的视图必须是这个调用约束的视图的祖先视图(这句话真心不懂怎么翻译),并且应该通常是最接近共同的祖先。(This is in the existing NSView
API sense of the word ancestor, 这句话真不懂翻译,当一个视图的祖先是它自己的时候)。这个约束被解释到这个视图的坐标系统中。
假设你安装了[zoomableView1]-80-[zoomableView2]在zoomableView1和zoomableView2中同一个祖先上。
The value 80 is in the coordinate system of the container, which is what it looks like if you draw the constraint.
If the bounds transform of either of the zoomable views changes, the space between them remains fixed.
这个值80是在容器的坐标系统中,这是它看起来像你再画这个约束。如果这两个视图的任意一个边界( bounds transform 真的很难翻译,因为iOS的bounds的概念就是建立在存在一个坐标系统中的 )发生了变化的话,他们之间的空间仍然是固定的。
If the bounds transform in the container itself is changed, the space scales, too.
如果容器本身的bounds transform发生了变化的话,这个空间会自动调整规模。
NSView
provides a method—addConstraint:
—to add a constraint, and methods to remove or inspect existing constraints—removeConstraint:
and constraints
—as well as other related methods. NSView
also provides a method, fittingSize
,which is similar to the sizeToFit
method of NSControl
but for arbitrary views rather than for controls.
The fittingSize
method returns the ideal size for the view considering only those constraints installed on the receiver’s subtree together with a preference for the view to be as small as possible. The fitting size is not the “best” size for a view in a general sense—in the constraint-based system, a view’s “best” size (if you consider everything) is by definition its current size.
addConstraint:
—去增加约束,还有删除和检查已经存在的约束-removeConstraint:还有 constraints
—和其他相关的方法。NSView也提供了一个方法,fittingSize,这个方法和NSControl的方法sizeToFit对于任意的视图而不是控制一样。
这个fittingSize方法为视图返回了一个理想的大小只考虑到那些被安装在接收方的子树和视图的偏好一起来使得尽可能小。一般来说,这个适合大小对于视图来说并不是“最优的”——在基于约束的系统,视图的“最优”大小(如果你考虑到任何事情的话)由定义出发是当前值。