iOS Auto Layout Demystified(2nd)

Constraint

Priorities

Constraint priorities are numbers that express how strongly Auto Layout considers each layout request. Auto Layout uses priorities to resolve constraint conflicts and decide which rule takes precedence.(Constraint priorities是一个数字用来表示Auto Layout的强弱。Auto Layout使用priorities来解决constraint的冲突和它们的优先权。)

The priority ranges from 1 (lowest priority) to 1,000 (required priority).优先级的范围是从1到1000 Strictly speaking, priori- ties are floats:

typedef float UILayoutPriority; 
typedef float NSLayoutPriority;

UIKit UIView Priorities

enum 
{
    UILayoutPriorityRequired = 1000, // Required
    UILayoutPriorityDefaultHigh = 750, // Compression resistance default
    UILayoutPriorityDefaultLow = 250, // Compression hugging default
    UILayoutPriorityFittingSizeLevel = 50, // System layout fitting size
};
typedef float UILayoutPriority;

Creating Layout Constraints

You build layout constraints in any of three ways建layout约束的三种方式 :

  1. You can use IB to design your interfaces. IB can generate constraints that support your layout. You can further customize the set of constraints from within the visual editor.

  2. You can use a visual formatting language to describe your constraints and allow the NSLayoutConstraint class to generate individual instances from your request (constraintsWithVisualFormat:options:metrics:views:).

  3. You can build instances of the NSLayoutConstraint class by supplying each component of a base relation (constraintWithItem:attribute: relatedBy:toItem:attribute: multiplier:constant:).

Building Layout Constraints

Layout constraints (instances of NSLayoutConstraint) define rules about a view’s physical geometry. They specify how a view should be laid out and how a view relates to other views in the same hierarchy. Elements of Constraints

The Layout Constraint Class

You create mathematical rules by building instances of the NSLayoutConstraint class and adding them to your views. Instances offer the following base properties(创建精确的规则通过建实例化的NSLayoutConstraint class并且添加在views 里):

  • priority—This attribute stores a constraint’s priority value. Priorities allow the Auto Layout system to rank constraints to choose which requests to honor.
  • firstItem and secondItem—These properties point to views. A constraint may talk about the properties of one view or the relation between two views. A valid constraint always has a non-nil first item. The second item may or may not be nil.
  • firstAttribute and secondAttribute—Attributes are the “nouns” of the constraint system, describing features of a view’s alignment rectangle, such as left, right, center, and height. These properties are set to any of the 12 enumerated attributes. If you don’t have a second item, you set the second attribute to NSLayoutAttributeNotAnAttribute.
  • relation—Relations are the “verbs” of the constraint system, specifying how attributes compare to each other: the same (==), greater than or equal to (>=), or less than or equal to (<=).
  • multiplier and constant—These properties provide the algebra that gives the constraint system its power and flexibility. They allow you to say one view is half the size of another or that a view is offset from its superview by a set distance. These properties are both floating-point values. They correspond to the m (multiplier) and b (constant) elements used to form the constraint equation. You can ignore any multiplier of 1 or constant of 0; they are identity operations.

    Constraint Math

    All constraints, regardless of how they are created, are essentially equations or inequalities with the following form:所有的约束都可以看成下面的公式

    y (relation) m * x + b
    view1.attribute (relation) view2.attribute * multiplier + constant
    

    First and Second Items

    Every relation equation you build looks like this, with the multiplier (m) and constant (b) always applying to the second item:

    firstItem.firstAttribute (R) secondItem.secondAttribute * m + b

    eg:

    View B’s left = View A’s right + 10
    View A’s right = View B’s left – 10
    [viewA]-10-[viewB]
    

    Building NSLayoutConstraint Instances

    The NSLayoutConstraint’s class method constraintWithItem:attribute: relatedBy: toItem:attribute:multiplier:constant: (gesundheit!) creates a single constraint at a time. Each layout constraint defines a rule about either one or two views. With two views, the creation method produces a strict view.attribute R view.attribute * multiplier + constant relation, where R is one of equal-to (==), greater-than-or-equal-to (>=), or less-than- or-equal-to (<=) relations.

    1.

    [self.view addConstraint:
    [NSLayoutConstraint
    constraintWithItem:self.view 
    attribute:NSLayoutAttributeCenterX 
    relatedBy:NSLayoutRelationEqual 
    toItem:textfield attribute:NSLayoutAttributeCenterX 
    multiplier:1
    constant:0]];
    

    The multi- plier here is 1, and the offset constant is 0. This represents the following equation:

    [self.view]’s centerX = ([textfield]’s centerX * 1) + 0

    2.

    Unary Constraints一元的约束

    NSLayoutConstraint *constraint = 
    [NSLayoutConstraint constraintWithItem:view 
    attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationGreaterThanOrEqual 
    toItem:nil 
    attribute:NSLayoutAttributeNotAnAttribute 
    multiplier:1
    constant:100];
    [view addConstraint:constraint];
    

    This constraint corresponds to the following rule:上面的约束相当于下面这个公式

    [view]’s width >= 100

    3.

    Zero-Item Constraints Are Illegal(0个item的约束是不合法的)

    [self.view addConstraint:
    [NSLayoutConstraint
    constraintWithItem:nil 
    attribute:NSLayoutAttributeNotAnAttribute relatedBy:NSLayoutRelationEqual 
    toItem:nil 
    attribute:NSLayoutAttributeNotAnAttribute 
    multiplier:1 
    constant:0]]
    

    It compiles properly, without warnings. When run, however, it raises an exception:

    2013-01-17 12:14:37.653 HelloWorld[17700:c07] Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: ' +[NSLayoutConstraint constraintWithItem:attribute:relatedBy: toItem:attribute:multiplier:constant:]: Constraint must contain a first layout item'

Installing Constraints

To get constraints to enter the Auto Layout system, you add them to views. Here’s an example:

[myView addConstraint: aConstraintInstance];

Because the visual format system returns arrays of constraints rather than single constraints, the NSLayoutConstraint class also offers a way to add a collection of constraints simultaneously:

[myView addConstraints: myArrayOfConstraints];

Removing Constraints

You can add and remove constraints from views at any time. The two built-in methods removeConstraint: and removeConstraints: enable you to remove one or an array of constraints from a given view. Because these methods work on object pointers, they might not do what you expect when you attempt to remove constraints.你能在任何时间添加和移除约束从views里。有两个方法removeConstraint:和removeConstraints:移除一个和多个约束从给定的view里面。

NSLayoutConstraint *myConstraint = NSLayoutConstraint constraintWithItem:textField
attribute:NSLayoutAttributeCenterX 
relatedBy:NSLayoutRelationEqual 
toItem:self.view attribute:NSLayoutAttributeCenterX 
multiplier:1.0f constant:0.0f]];
[self.view addConstraint:myConstraint];
// later
[self.view removeConstraint:myConstraint];

Comparing Constraints

All constraints use a fixed structure of the following form, along with an associated priority:所有约束都使用以下形式,连同关联的优先级固定的结构

view1.attribute (relation) view2.attribute * multiplier + constant
@implementation NSLayoutConstraint (ConstraintMatching)

// This ignores any priority, looking only at y (R) mx + b
- (BOOL) isEqualToLayoutConstraint: (NSLayoutConstraint *) constraint {
if (self.firstItem != constraint.firstItem) return NO;
if (self.secondItem != constraint.secondItem) return NO;
if (self.firstAttribute != constraint.firstAttribute) return NO; if (self.secondAttribute != constraint.secondAttribute) return NO; if (self.relation != constraint.relation) return NO;
if (self.multiplier != constraint.multiplier) return NO;
if (self.constant != constraint.constant) return NO;
return YES; }
@end