AutoLayout是什么?
使用一句Apple的官方定义的话
AutoLayout是一种基于约束的,描述性的布局系统。
每个UIView都会有自己的frame属性,来定义其在当前视图中的位置和尺寸。使用AutoLayout的话,就变为了使用约束条件来定义view的位置和尺寸
以前采用的Autoresizing Mask方式和AutoLayout 有什么区别?
- AutoLayout可以指定任意(有共同的父视图的两个视图或者是父视图和子视图关系)两个view的相对位置,而不需要像Autoresizing Mask那样需要两个view在直系的视图层级中。
- AutoLayout不必须指定相等关系的约束,它可以指定非相等约束(大于或者小于等);而Autoresizing Mask所能做的布局只能是相等条件的。
- AutoLayout可以指定约束的优先级,计算frame时将优先按照满足优先级高的条件进行计算
Autolayout:最重要的两个概念:
* 约束:对控件位置和大小的限定条件
* 参照:对控件设置的约束是相对于哪一个视图而言的
约束:
约束类型:
内容大小约束:指定视图的尺寸和内容的关系
自动尺寸调整约束:将原来的自动尺寸调整掩码转换成自动布局的对应约束
布局约束:视图位置和尺寸
布局支持约束:防止视图内容和状态栏之类的障碍物重叠
原型约束:测试用
优先级(priority):
约束优先级是浮点数,优先级越大,执行强度越强
布局约束:
代码实现Autolayout的步骤
- 利用NSLayoutConstraint类创建具体的约束对象
- 添加约束对象到相应的view上
添加约束的3条规则:
- 对于两个同层级View之间的约束关系,应该添加到它们的父View之上。
同层级的View
- 对于两个不同层级View之间的约束关系,应该添加到它们最近的共同父View上。
不同层级的View
- 对于有层次关系的两个view之间的约束关系,添加到层次较高的父view上
有层级关系的View
代码实现Autolayout的注意点
- 要先禁止autoresizing功能,设置view的下面属性为NO
view.translatesAutoresizingMaskIntoConstraints = NO;
* 添加约束之前,一定要保证相关控件都已经在各自的父控件上
* 不用再给view设置frame
创建约束对象的常用方法
+(id)constraintWithItem:(id)view1
attribute:(NSLayoutAttribute)attr1
relatedBy:(NSLayoutRelation)relation
toItem:(id)view2
attribute:(NSLayoutAttribute)attr2
multiplier:(CGFloat)multiplier
constant:(CGFloat)c;
view1 :要约束的控件
attr1 :约束的类型(做怎样的约束)
relation :与参照控件之间的关系
view2 :参照的控件
attr2 :约束的类型(做怎样的约束)
multiplier :乘数
c :常量
约束的类型:
NSLayoutAttributeLeft // 左边约束类型
NSLayoutAttributeRight // 右边约束类型
NSLayoutAttributeTop // 顶部约束类型
NSLayoutAttributeBottom // 底部约束类型
NSLayoutAttributeLeading // 和NSLayoutAttributeLeft一样
NSLayoutAttributeTrailing // 和NSLayoutAttributeRight一样
NSLayoutAttributeWidth // 宽度约束
NSLayoutAttributeHeight // 高度约束
NSLayoutAttributeCenterX // 水平方向约束
NSLayoutAttributeCenterY // 垂直方向约束
自动布局的核心计算公式:
view1.attr1 = view2.attr2 * multiplier + constant
使用VFL(可视化格式化语言Visual Format Language)语句添加约束:
* VFL语言基本含义
“|”:父视图
“V:”:表示垂直方向上,这个方向的控件约束指的一般是高度或者垂直方向间距
“H:”:表示水平方向上,这个方向的控件约束指的一般是宽度或者水平方向间距
“-value-“:value表示一个约束的数值,一般指的是控件和控件或者屏幕边缘的间距值,
“-”用来隔开约束数值或者控件或者屏幕的一种作用
“[controls]”:controls表示一个控件对象,控件宽高用“(value)”衔接在控件名字后面(注意是包含在中括号里头的),
H:方向value代表宽度,V:方向value代表高度
“H:|-20-[controls(width)]”:表示controls控件宽为width,且水平方向距离左边屏幕边缘20px间距
“V:|-20-[controls(Height)]”:表示controls控件高度为Height,且垂直方向距离顶部屏幕20px间距
方法
+ (NSArray )constraintsWithVisualFormat:(NSString )format
options:(NSLayoutFormatOptions)opts
metrics:(NSDictionary*)metrics
views:(NSDictionary *)views;
- 它返回一组constraint.
- format是你的VFL字串
-options:约束类型
metrics是一个奇妙的字典,是你自己定义的。这个字典里面的key可以写在format字串中。编译器解析时,自动替换为metrics字典中的value。等下有例子。
views是需要constraint关系的所有view.(也可以是一个)
顺便提一下使用 Auto Layout 做动画的方法。UIView 中更新布局的相关方法:
- setNeedsLayout() //标记布局需要在下一个周期更新
- layoutIfNeeded() //立刻更新布局
- setNeedsUpdateConstraints() //标记约束需要在稍后更新,系统会调用下面的 updateConstraints()方法
- updateConstraints() //更新调用该方法的视图的约束
- updateConstraintsIfNeeded() //更新调用该方法的视图以及其子视图的约束
Masonry第三方约束框架
使用方法
* github下载地址:https://github.com/SnapKit/Masonry
* 添加Masonry文件夹的所有源代码到项目中
* 添加两个宏、导入主头文件
// 只要添加了这个宏,就不用带mas_前缀的方法或者属性了
define MAS_SHORTHAND
// 只要添加了这个宏,equalTo就等价于mas_equalTo
define MAS_SHORTHAND_GLOBALS
// 这个头文件一定要放在上面两个宏的后面
import “Masonry.h”
看一下Masonry支持哪一些属性
1
3
4
5
6
7
8
9
10
11
@property (nonatomic, strong, readonly) MASConstraint *left;
@property (nonatomic, strong, readonly) MASConstraint *top;
@property (nonatomic, strong, readonly) MASConstraint *right;
@property (nonatomic, strong, readonly) MASConstraint *bottom;
@property (nonatomic, strong, readonly) MASConstraint *leading;
@property (nonatomic, strong, readonly) MASConstraint *trailing;
@property (nonatomic, strong, readonly) MASConstraint *width;
@property (nonatomic, strong, readonly) MASConstraint *height;
@property (nonatomic, strong, readonly) MASConstraint *centerX;
@property (nonatomic, strong, readonly) MASConstraint *centerY;
@property (nonatomic, strong, readonly) MASConstraint *baseline;
这些属性与NSLayoutAttrubute的对照表如下
Masonry NSAutoLayout 说明
left NSLayoutAttributeLeft 左侧
top NSLayoutAttributeTop 上侧
right NSLayoutAttributeRight 右侧
bottom NSLayoutAttributeBottom 下侧
leading NSLayoutAttributeLeading 首部
trailing NSLayoutAttributeTrailing 尾部
width NSLayoutAttributeWidth 宽
height NSLayoutAttributeHeight 高
centerX NSLayoutAttributeCenterX 横向中点
centerY NSLayoutAttributeCenterY 纵向中点
baseline NSLayoutAttributeBaseline 文本基线
- API方法
基本所有属性和方法都是采用block方法来执行的
equalTo(value):value可以是int、CGFloat、CGSize类型、view.top等约束值,或者直接view(会自动填补默认对应的属性
and和with:都是修饰属性,返回的的是MASConstraintMaker对象本身
multipliedBy(value):乘数,value表示倍数值
offset(value):偏移值,value偏移值数值
insets(UIEdgeInsetsMake):插入位置,UIEdgeInsetsMake类型(上左下右)
- 约束类型
1.尺寸:width\height\size
2.边界:left\leading\right\trailing\top\bottom
3.中心点:center\centerX\centerY
4.边界:edges
- 方法
// 添加MAS_SHORTHAND宏后makeConstraints:等价于mas_makeConstraints:
// 这个方法只会添加新的约束
[view makeConstraints:^(MASConstraintMaker *make) {
}];
// 这个方法会将以前的所有约束删掉,添加新的约束
[view remakeConstraints:^(MASConstraintMaker *make) {
}];
// 这个方法将会覆盖以前的某些特定的约束
[view updateConstraints:^(MASConstraintMaker *make) {
}];