AutoLayout(自动布局)是iOS中一种简单却高效的屏幕适配技术,它在Xcode 5中被支持,在新建工程时会被默认添加。
AutoLayout实现布局的原理是有精确的数学描述,为了便于理解,我先使用storyboard实现一个水平三等分的自动布局,然后再通过代码实现相同功能。
- 新建xcode工程,工程名为AutoLayout
进入Main.storyboard,然后先拖拽一个UIView(outside),作为外部的容器,设置背景色,设置自动布局,然后再分别拖入3个Uiview(inner),设置子视图的自动布局。
运行结果:
xcode 6.3.1
Mac OS X 10.10.3
simulator iOS 8.3 iphone
- xcode并未输出那种一大堆的提示:存在多余约束… 证明 storyboard方式实现自动布局已经成功。
下面使用纯代码的方式实现上面的效果
- 为工程添加一个新的Targets 名为:CodeAutoLayout
- 选择新的Targets,然后定位到ViewController.m中,在这里添加代码实现自动布局效果
- (void)viewDidLoad {
[super viewDidLoad];
// outsideView
// 1.创建outsideView
UIView *outsideView = [[UIView alloc] init];
// 2.关闭translatesAutoresizing
outsideView.translatesAutoresizingMaskIntoConstraints = NO;
// 要先添加到view中,然后再设置约束
[self.view addSubview:outsideView];
// 设置约束
// 水平约束 使用VFL语言 |-0-[outsideView]-0-| outside距左右屏幕都为0
NSArray *outsideHorContrains = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|-0-[outsideView]-0-|" options:0 metrics:nil views:@{@"outsideView":outsideView}];
// 垂直约束
NSArray *outsideVerContrains = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|-100-[outsideView(120)]" options:0 metrics:nil views:@{@"outsideView":outsideView}];
// 添加约束
[self.view addConstraints:outsideHorContrains];
[self.view addConstraints:outsideVerContrains];
// 设置背景色
outsideView.backgroundColor = [UIColor greenColor];
// innerView
// 创建innerView视图
UIView *inner_left = [[UIView alloc] init];
UIView *inner_center = [[UIView alloc] init];
UIView *inner_right = [[UIView alloc] init];
// 同样关闭...
inner_left.translatesAutoresizingMaskIntoConstraints = NO;
inner_center.translatesAutoresizingMaskIntoConstraints = NO;
inner_right.translatesAutoresizingMaskIntoConstraints = NO;
// 添加到outsideView中
[outsideView addSubview:inner_left];
[outsideView addSubview:inner_center];
[outsideView addSubview:inner_right];
// 设置水平约束
NSArray *innerHorContrains = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|-15-[inner_left(==inner_center)]-15-[inner_center]-15-[inner_right(==inner_center)]-15-|" options:NSLayoutFormatAlignAllCenterY metrics:nil views:@{@"inner_left":inner_left,@"inner_center":inner_center,@"inner_right":inner_right}];
// 设置垂直约束
NSArray *innerVerContrains = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|-20-[inner_center(80)]" options:0 metrics:nil views:@{@"inner_center":inner_center}];
// innerLeft 的高度 要求等于 inner_center 即 80
// 这段代码等价于一个等式
// inner_left . height == inner_center . height
// 详情可以查看API说明
NSLayoutConstraint *innerLeftHeightContrains = [NSLayoutConstraint constraintWithItem:inner_left attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:inner_center attribute:NSLayoutAttributeHeight multiplier:1.0 constant:0];
NSLayoutConstraint *innerRightHeightContrains = [NSLayoutConstraint constraintWithItem:inner_right attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:inner_center attribute:NSLayoutAttributeHeight multiplier:1.0 constant:0];
// 添加约束到视图中 父-子间约束 添加到 父视图
[outsideView addConstraints:innerHorContrains];
[outsideView addConstraints:innerVerContrains];
// 兄弟间约束 添加到 父视图
[outsideView addConstraint:innerLeftHeightContrains];
[outsideView addConstraint:innerRightHeightContrains];
// 设置背景色
inner_left.backgroundColor = [UIColor whiteColor];
inner_center.backgroundColor = [UIColor whiteColor];
inner_right.backgroundColor = [UIColor whiteColor];
}
command + R 运行得到的效果与storyboard的效果一致
关键点
1.要理解NSLayoutContraint的两个类方法
2.VFL(可视化格式语言)的写法
3.子视图的宽度 = (屏幕宽度<变量> - 4 * 间距) / 3
4.约束该添加的视图(父-子 添加到父视图,兄-弟 添加到父视图 自身<宽,高> 添加到自身
注:布局的方法有很多,比如左右的高度也可以直接设置约束为80,在这里为了更加统一,因此两边的子视图的约束都是与中间的子视图来产生联系。
最后说两句
在理解自动布局的约束原理的基础上,使用storyboard明显更加方便。还有xcode在storyboard中也提供了布局预览的工具(有时候不太好用)。如果对storyboard自动布局依然有问题的话,可以git源程序