AutoLayout自动布局介绍
UI布局对于iOS开发者来说并不陌生,在iOS6之前,大家都是通过UI控件的Frame属性和Autoresizing Mask来进行UI布局的。AutoLayout则是苹果公司在iOS6推出的一种基于约束的,描述性的布局系统。自从AutoLayout问世以来,逐步得到了iOS开发者们的青睐,尤其是iPhone6机型尺寸的出现。
AutoLayout占据UI布局的主要领导位置依赖于它的特殊性:
- 基于约束:和以往定义frame的位置和尺寸不同,AutoLayout的位置确定是以所谓相对位置的约束来定义的,比如x坐标为superView的中心,y坐标为屏幕底部上方10像素等
- 描述性: 约束的定义和各个view的关系使用接近自然语言或者可视化语言(稍后会提到)的方法来进行描述
- 布局系统:即字面意思,用来负责界面的各个元素的位置。
AutoLayout使用原理
创建约束
IOS6中新加入了一个类,NSLayoutConstraint
,它的约束满足一个公式
1 | item1.attribute = multiplier ⨉ item2.attribute + constant |
相应公式的代码为1
2
3
4
5
6
7
8//view_1(红色)top 距离self.view的top
NSLayoutConstraint *view_1TopToSuperViewTop = [NSLayoutConstraint constraintWithItem:view_1
attribute:NSLayoutAttributeTop
relatedBy:NSLayoutRelationEqual
toItem:self.view
attribute:NSLayoutAttributeTop
multiplier:1
constant:30];
这里对应的约束是“view_1的顶部(y)= self.view的顶部(y)*1 + 30”。
添加约束
在创建约束后,需要将其添加到作用的view上。UIView添加约束的实例方法
1 | - (void)addConstraint:(NSLayoutConstraint *)constraint NS_AVAILABLE_IOS(6_0); |
UIView中的一个属性translatesAutoresizingMaskIntoConstraints
1 | //如果你定义的view想用autolayout,就将 |
约束的属性
名称 | autolayout 对应属性 | 意义 |
---|---|---|
left | NSLayoutAttributeLeft | 左边框 |
top | NSLayoutAttributeTop | 上边框 |
right | NSLayoutAttributeRight | 右边框 |
bottom | NSLayoutAttributeBottom | 下边框 |
centerX | NSLayoutAttributeCenterX | center的X坐标 |
centerY | NSLayoutAttributeCenterY | center的Y坐标 |
width | NSLayoutAttributeWidth | 宽度 |
height | NSLayoutAttributeHeight | 高度 |
leading | NSLayoutAttributeLeading | 正常情况下等同于left |
trailing | NSLayoutAttributeTrailing | 正常情况下等同于right |
baseline | NSLayoutAttributeBaseline | 对齐基线 |
leftMargin | NSLayoutAttributeLeftMargin | 左边的Margin |
rightMargin | NSLayoutAttributeRightMargin | 右边的Margin |
topMargin | NSLayoutAttributeTopMargin | 顶部的Margin |
bottomMargin | NSLayoutAttributeBottomMargin | 底部的Margin |
leadingMargin | NSLayoutAttributeLeadingMargin | 前导(基本等于left)Margin |
trailingMargin | NSLayoutAttributeTrailingMargin | 后尾(基本等于tail)Margin |
centerXWithinMargins | NSLayoutAttributeCenterXWithinMargins | 中心X坐标Margin |
centerYWithinMargins | NSLayoutAttributeCenterYWithinMargins | 中心Y坐标Margin |
当然,如何添加也有相应的规则。
对其他的view没有任何关系时,添加到自己的view上
比如说添加一个按钮的宽和高的约束,对其他的view没有任何关系,则将约束添加到自己身上。
为按钮添加一个宽和高为两百的约束1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
@interface ViewController ()
@property (strong, nonatomic) IBOutlet UIButton *btn1;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
NSLayoutConstraint *c1 = [NSLayoutConstraint constraintWithItem:self.btn1 attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeWidth multiplier:1 constant:200];
NSLayoutConstraint *c2 = [NSLayoutConstraint constraintWithItem:self.btn1 attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeHeight multiplier:1 constant:200];
self.btn1.translatesAutoresizingMaskIntoConstraints = NO;
[self.btn1 addConstraint:c1];
[self.btn1 addConstraint:c2];
}
@end
对于两个同层级view之间的约束关系,则添加到他们的父View上
例如3.1
与3.2
为同层级view,约束关系则添加到父view2.1
上。
添加了一个蓝色view的上边线与绿色view的下边线对其的约束,两个view为同级约束,则添加到了父view上。
对于两个不同层级的view之间的约束关系,则添加到它们最近的共同的父view上
例如3.3
与3.5
为同层级view,约束关系则添加到父view1
上。
但是相对于这种情况应该用的很少。
对于两个有层次关系的view之间的约束关系,则添加到层次较高的那个view上
例如1
和2.3
为父子关系的view,约束关系则添加到view1
上
刷新约束
可以通过setNeedsUpdateConstraints
和layoutIfNeeded
两个方法来刷新约束,使得UIView重新布局。
Masonry框架
Masonry是AutoLayout的一个第三方类库,用链式语法封装了冗长的AutoLayout代码
1 | - (NSArray *)mas_makeConstraints:(void(^)(MASConstraintMaker *make))block; |
常用属性
1 | //乘以 |
Visual Format Language
VFL(Visual Format Language)允许你使用一种ASCII格式的字符串定义约束. 通过一行代码, 你可以在水平或者垂直方向上指定多个约束, 这跟一次只能创建一个约束相比会节省大量的代码量。
- 创建水平和垂直约束
- 在VFL中使用
views
- 在VFL中使用
metrics
- 使用layout options布局界面
- 使用layout guides