Auto Layout 学习

Auto Layout 是苹果在 iOS 6.0后引入的自动布局工具,可以通过设置各组件间的约束进行自动布局。

约束数学

1
2
3
4
5
// y R m * x + b
// R 指 y 与右边算式值得关系
// m 是常数缩放因子
// b 是常数偏移值
firstItem.attribute (R) secondItem.aattribute * m + b

介绍

使用方式

1
2
// 默认为 YES,使用 autoresizingMask 进行计算,设为 NO 时使用 AutoLayout 布局
self.translatesAutoresizingMaskIntoConstraints = NO;

NSLayoutConstraint

  • 可视化格式

    1
    2
    3
    4
    + (NSArray<__kindof NSLayoutConstraint *> *)constraintsWithVisualFormat:(NSString *)format // 传入的表达式
    options:(NSLayoutFormatOptions)opts // 选项
    metrics:(nullable NSDictionary<NSString *,id> *)metrics // 度量字典
    views:(NSDictionary<NSString *, id> *)views; // 变量字典
  • 单个约束

    1
    2
    3
    4
    5
    6
    7
    +(instancetype)constraintWithItem:(id)view1 // 被约束对象
    attribute:(NSLayoutAttribute)attr1 // 被约束对象的属性
    relatedBy:(NSLayoutRelation)relation // 约束关系
    toItem:(nullable id)view2 // 约束源
    attribute:(NSLayoutAttribute)attr2 // 约束源的属性
    multiplier:(CGFloat)multiplier // 约束系数
    constant:(CGFloat)c; // 约束常数

Interface Builder

拖拽添加

属性和关系

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
// 约束属性
typedef NS_ENUM(NSInteger, NSLayoutAttribute) {
NSLayoutAttributeLeft = 1, // 左边
NSLayoutAttributeRight, // 右边
NSLayoutAttributeTop, // 顶部
NSLayoutAttributeBottom, // 底部
NSLayoutAttributeLeading, // 首部
NSLayoutAttributeTrailing, // 尾部
NSLayoutAttributeWidth, // 宽度
NSLayoutAttributeHeight, // 高度
NSLayoutAttributeCenterX, // X轴中心
NSLayoutAttributeCenterY, // Y轴中心
NSLayoutAttributeBaseline, // 文本底标线 一般等同于NSLayoutAttributeBottom,但在少数视图,如UILabel,是指字母的底部
NSLayoutAttributeBaseline NS_SWIFT_UNAVAILABLE("Use 'lastBaseline' instead") = NSLayoutAttributeLastBaseline, // 相当于NSLayoutAttributeBaseline
NSLayoutAttributeFirstBaseline NS_ENUM_AVAILABLE_IOS(8_0), // 文本上标线

// 意义和上面类似
NSLayoutAttributeLeftMargin NS_ENUM_AVAILABLE_IOS(8_0),
NSLayoutAttributeRightMargin NS_ENUM_AVAILABLE_IOS(8_0),
NSLayoutAttributeTopMargin NS_ENUM_AVAILABLE_IOS(8_0),
NSLayoutAttributeBottomMargin NS_ENUM_AVAILABLE_IOS(8_0),
NSLayoutAttributeLeadingMargin NS_ENUM_AVAILABLE_IOS(8_0),
NSLayoutAttributeTrailingMargin NS_ENUM_AVAILABLE_IOS(8_0),
NSLayoutAttributeCenterXWithinMargins NS_ENUM_AVAILABLE_IOS(8_0),
NSLayoutAttributeCenterYWithinMargins NS_ENUM_AVAILABLE_IOS(8_0),

NSLayoutAttributeNotAnAttribute = 0 // 没有属性
};
1
2
3
4
5
6
// 约束关系
typedef NS_ENUM(NSInteger, NSLayoutRelation) {
NSLayoutRelationLessThanOrEqual = -1, // 小于等于
NSLayoutRelationEqual = 0, // 等于
NSLayoutRelationGreaterThanOrEqual = 1, // 大于等于
};

注意

  • 充分性
    欠约束的布局会产生随机结果

  • 可满足性
    建立的规则必须在单独使用和作为整体使用时都有意义

压缩与吸附

  • 压缩阻力

压缩阻力是指视图保护其内容的方式。压缩阻力高的视图能够抵抗收缩,不允许内容被剪切。

1
2
3
// 设置的值可以再1(最低优先级)到100(必需的优先级)之间,默认值为750
[view setContentCompressionResistancePriority:500
forAxis:UILayoutConstraintAxisHorizontal];
  • 内容吸附
    内容吸附是防止在视图与其核心内容间作填充或直接伸展其核心内容。
1
2
3
// 范围与压缩阻力相同,默认值也为250
[view setContentHuggingPriority:501
forAxis:UILayoutConstraintAxisHorizontal];

调试

添加 Symbolic Breakpoint

Symbol 中填写UIViewAlertForUnsatisfiableConstraints

现在 Auto Layout 遇到异常时 Xcode 会自动在异常位置断住

《iOS Auto Layout开发秘籍(第二版)》