一、Auto Layout
1. 苹果官方是如何描述Auto Layout的:Auto Layout 是一个系统,可以让你通过创建元素之间关系的数学描述来布局应用程序的用户界面,是一种基于约束的,描述性的布局系统
2. 注意上述的一点 : 布局是设置在两个 view 间的一种约束,所以我们不能只设置一个 view 的约束,这样做没有什么意义,它必须是相对的
3. 所有的布局都遵循以下的公式
view1.property = (view.2property * multiplier) + constant
翻译过来就是 : view1 的某个属性的值 = (view2的某个属性的值 * 系数)+ 常量
二、Autoresizing Mask
1. 在我们为 view 设置约束条件时,必须将其下面这个
属性设置为 NO,该属性默认为 YES
@property(nonatomic)BOOL translatesAutoresizingMaskIntoConstraintsNS_AVAILABLE_IOS(6_0);
当它为 YES 时,系统会自动将 Autoresizing Mask 转换为 Auto Layout 的约束,这样会和我们设置的约束发生冲突
但是在 XIB/Storyboard 中,系统会自动将我们帮这个属性设置为 NO,即在 XIB/Storyboard 中勾选了 Use AutoLayout 后,AutoResizing Mask 就被废弃
三、NSLayoutConstraint
官方 API 提供的是 NSLayoutConstraint 类,一个 NSLayoutConstraint 类的对象就代表一条约束
该类有一个类方法用来创建约束对象,这个方法是最常用的
// 参数 1 : 需要添加约束的 view // 参数 2 : 需要填加的约束(左边、右边、宽度、高度等) // 参数 3 : 约束关系(大于、小于、相等) // 参数 4 : 参数 view(约束是相对于哪个 view 而言) // 参数 5 : 参照 view 的哪一个参数(左边、右边、宽度、高度等) // 参数 6 : 系数 // 参数 7 : 常量 +(instancetype)constraintWithItem:(id)view1 attribute:(NSLayoutAttribute)attr1 relatedBy:(
)relation toItem:(nullable id)view2 attribute:(NSLayoutAttribute)attr2 multiplier:(CGFloat)multiplier constant:(CGFloat)c;NSLayoutRelation
NSLayoutAttribute 枚举如下
typedef NS_ENUM(NSInteger, NSLayoutAttribute) {
NSLayoutAttributeLeft = 1, // 左边,永远指左边
NSLayoutAttributeRight, // 右边,永远指有伴
NSLayoutAttributeTop, // 顶部
NSLayoutAttributeBottom, // 底部
NSLayoutAttributeLeading, // 前面,在某些从右至左为习惯的的确会变成右边
NSLayoutAttributeTrailing, // 后面,在某些从右至左为习惯的的确会变成左边
NSLayoutAttributeWidth, // 宽度
NSLayoutAttributeHeight, // 高度
NSLayoutAttributeCenterX, // 中点的 X 值
NSLayoutAttributeCenterY, // 中点的 Y 值
NSLayoutAttributeLastBaseline, // 基准线:位于视图底部上方放置文字的地方
NSLayoutAttributeBaseline NS_SWIFT_UNAVAILABLE("Use 'lastBaseline' instead") = NSLayoutAttributeLastBaseline,
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 // 没有属性
};
NSLayoutRelation枚举如下
typedef NS_ENUM(NSInteger, NSLayoutRelation) {
NSLayoutRelationLessThanOrEqual = -1, // 小于或等于(先使用等于,如果等于不满足再使用小于)
NSLayoutRelationEqual = 0, // 等于
NSLayoutRelationGreaterThanOrEqual = 1, // 大于或等于(先使用等于,如果等于不满足再使用大于)
};
假如设置某个 view的约束是大于等于50,那么首先会使用50,当视图被拉伸的时候,50就无法满足,此时就会使用大于50的值
2. 实例一:设置子视图在父视图中,并且上下左右到父视图的上下左右都距离 50
self.view.backgroundColor = [UIColor yellowColor];
// 创建视图
UIView * view = [[UIView alloc] init];
// 设置背景色
view.backgroundColor = [UIColor greenColor];
// 添加
[self.view addSubview:view];
// 关闭系统自定义布局
view.translatesAutoresizingMaskIntoConstraints = NO;
// 设置 子视图左侧距离父视图左侧 50
NSLayoutConstraint * LC1 = [NSLayoutConstraint constraintWithItem:view attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeLeft multiplier:1.0 constant:50];
// 设置 子视图顶部距离 父视图顶部 50
NSLayoutConstraint * LC2 = [NSLayoutConstraint constraintWithItem:view attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeTop multiplier:1.0 constant:50];
// 设置 子视图右侧距离 父视图右侧 50
NSLayoutConstraint * LC3 = [NSLayoutConstraint constraintWithItem:view attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeRight multiplier:1.0 constant:-50];
// 设置 子视图底部距离 父视图底部 50
NSLayoutConstraint * LC4 = [NSLayoutConstraint constraintWithItem:view attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeBottom multiplier:1.0 constant:-50];
// 将子视图的约束添加到父视图上
[self.view addConstraints:@[LC1, LC2, LC3, LC4]];
效果如图
3、实例二:子视图在父视图中间,且 width 为 300,height 为 200
// 创建 UIView 对象
UIView * view = [[UIView alloc] init];
view.backgroundColor = [UIColor blueColor];
view.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addSubview:view];
// 场景二 :子视图在父视图中间,且width 300,height 200
NSLayoutConstraint * centerX = [NSLayoutConstraint constraintWithItem:view attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeCenterX multiplier:1.0 constant:0];
NSLayoutConstraint * centerY = [NSLayoutConstraint constraintWithItem:view attribute:NSLayoutAttributeCenterY relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeCenterY multiplier:1.0 constant:0];
NSLayoutConstraint * height = [NSLayoutConstraint constraintWithItem:view attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationGreaterThanOrEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0 constant:200];
NSLayoutConstraint * width = [NSLayoutConstraint constraintWithItem:view attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationGreaterThanOrEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0 constant:300];
[self.view addConstraints:@[centerX, centerY, height, width]];
效果如下