Apple在2012年发布了新的手机iphone5,手机屏幕尺寸也变成了4寸,由此带来了跟Android一样的适配问题,基于这种情况,Apple开始大力推行AutoLayout的UI布局方式,最近正好学习AutoLayout,随笔记录下。
什么是AutoLayout?
在苹果官方的定义是:AutoLayout是一种基于约束的,描述性的布局系统。 Auto Layout Is a Constraint-Based, Descriptive Layout System.
1.基于约束的 -- 跟以往的定义frame的坐标和大小不同是,AutoLayout的坐标是以相对坐标的约束来定义的。比如x坐标是superView的中心,y坐标是距离顶部10pt。
2.描述性 -- 相对坐标的约束定义使用可视化语言来描述
3.布局系统 -- 负责界面各个元素的位置
在没有AutoLayout之前,我们在定义view时,不论用代码还是xib创建都会定义好view的frame属性,在确定view在superView中的位置和尺寸,而在AutoLayout中,就要使用约束条件来定义view的位置和尺寸。使用AutoLayout解决了不同尺寸下view的适配问题以及屏幕翻转view的位置。
AutoLayout的基本使用方法
1.xib中添加
创建一个xib,在其中添加一个view,在其File Inspector勾选Use AutoLayout选项。(如果你没有这个选项,检查自己的xcode版本是不太低了。。。)
添加view成功后会自动添加约束,如果没有自动添加约束,选中view,在右下角的位置点击第二个工具添加,或者选中view,点击Editor -> Pin添加。添加要加的约束条件后点击add就可以。
Width:固定自身的宽度
Height:固定自身的高度
Horizontal Spacing:两个view之间的水平间距
Vertical Spacing:两个view之间的垂直间距
Leading(Trailing Top Bottom) Space to SuperView:相对于superView的左右上下的间距
Widths Equally:两个view宽度保持相同
Heights Equally:两个view高度保持相同
添加成功后,在左侧的view概要中会有一个section叫“Constraints”。你所添加的所有的约束都在这个section下。
上三张图,一个是Xib中添加的约束,一个是运行后竖屏的图,一个是运行后横屏的图
2.手动使用API添加约束
2.1在IOS6中新加入了一个类: NSLayoutConstraint
创建一个约束
[NSLayoutConstraint constraintWithItem:button attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:superview attribute:NSLayoutAttributeBottom multiplier:1.0 constant:-padding]
这个约束标示 button.底部 = superView.底部 - 10
创建完成调用如下方法添加到作用的view上。
-(void)addConstraint:(NSLayoutConstraint *)constraint;
上代码 下面的代码是实现了跟xib添加的约束一样的效果
UIButton * btn1 = [UIButton buttonWithType:UIButtonTypeCustom];
[btn1 setBackgroundColor:[UIColor redColor]];
[btn1 setTitle:@"view01" forState:UIControlStateNormal];
[btn1 setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
btn1.titleLabel.font = [UIFont systemFontOfSize:15.0f];
[self.view addSubview:btn1];
UIButton * btn2 = [UIButton buttonWithType:UIButtonTypeCustom];
[btn2 setBackgroundColor:[UIColor cyanColor]];
[btn2 setTitle:@"view02" forState:UIControlStateNormal];
[btn2 setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
btn2.titleLabel.textColor = [UIColor blackColor];
btn2.titleLabel.font = [UIFont systemFontOfSize:15.0f];
[self.view addSubview:btn2];
UIButton * btn3 = [UIButton buttonWithType:UIButtonTypeCustom];
[btn3 setBackgroundColor:[UIColor magentaColor]];
[btn3 setTitle:@"view03" forState:UIControlStateNormal];
[btn3 setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
btn3.titleLabel.textColor = [UIColor blackColor];
btn3.titleLabel.font = [UIFont systemFontOfSize:15.0f];
[self.view addSubview:btn3];
[btn1 setTranslatesAutoresizingMaskIntoConstraints:NO];
[btn2 setTranslatesAutoresizingMaskIntoConstraints:NO];
[btn3 setTranslatesAutoresizingMaskIntoConstraints:NO];
if ([self.view respondsToSelector:@selector(addConstraint:)]) {
}
//创建约束
//btn1 距离顶部20
NSLayoutConstraint * aCons = [NSLayoutConstraint constraintWithItem:btn1 attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeTop multiplier:1 constant:20.0f];
[self.view addConstraint:aCons];
//btn1 距离左边距20
NSLayoutConstraint * bCons = [NSLayoutConstraint constraintWithItem:btn1 attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeLeft multiplier:1 constant:20.0f];
[self.view addConstraint:bCons];
//btn1和bnt2间距20
NSLayoutConstraint * cCons = [NSLayoutConstraint constraintWithItem:btn1 attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:btn2 attribute:NSLayoutAttributeLeft multiplier:1 constant:-20.0f];
[self.view addConstraint:cCons];
//btn2 距离顶部20
NSLayoutConstraint * dCons = [NSLayoutConstraint constraintWithItem:btn2 attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeTop multiplier:1 constant:20.0f];
[self.view addConstraint:dCons];
//btn2 距离右边距20
NSLayoutConstraint * eCons = [NSLayoutConstraint constraintWithItem:btn2 attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeRight multiplier:1 constant:-20.0f];
[self.view addConstraint:eCons];
//btn1和btn2的width相同
NSLayoutConstraint * fCons = [NSLayoutConstraint constraintWithItem:btn1 attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:btn2 attribute:NSLayoutAttributeWidth multiplier:1 constant:0];
[self.view addConstraint:fCons];
//btn3 距离底部20
NSLayoutConstraint * gCons = [NSLayoutConstraint constraintWithItem:btn3 attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeBottom multiplier:1 constant:-20.0f];
[self.view addConstraint:gCons];
//btn3 距离左边距20
NSLayoutConstraint * hCons = [NSLayoutConstraint constraintWithItem:btn3 attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeLeft multiplier:1 constant:20.0f];
[self.view addConstraint:hCons];
//btn3和btn1上下间距20
NSLayoutConstraint * iCons = [NSLayoutConstraint constraintWithItem:btn1 attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:btn3 attribute:NSLayoutAttributeTop multiplier:1 constant:-20.0f];
[self.view addConstraint:iCons];
//btn3和btn1高度相同
NSLayoutConstraint * jCons = [NSLayoutConstraint constraintWithItem:btn1 attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:btn3 attribute:NSLayoutAttributeHeight multiplier:1 constant:0];
[self.view addConstraint:jCons];
//btn3和btn2高度相同
NSLayoutConstraint * kCons = [NSLayoutConstraint constraintWithItem:btn2 attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:btn3 attribute:NSLayoutAttributeHeight multiplier:1 constant:0];
[self.view addConstraint:kCons];
//btn3 距离右边距20
NSLayoutConstraint * lCons = [NSLayoutConstraint constraintWithItem:btn3 attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeRight multiplier:1 constant:-20.0f];
[self.view addConstraint:lCons];
2.2 VFL
VFL Visual Format Language 可视格式语言
+ (NSArray *)constraintsWithVisualFormat:(NSString *)format options:(NSLayoutFormatOptions)opts metrics:(NSDictionary *)metrics views:(NSDictionary *)views;
使用VFL
NSDictionary * dict = NSDictionaryOfVariableBindings(btn1,btn2,btn3);
NSDictionary * metrics = @{@"padding":@20.0f};
NSString * vfla = @"|-padding-[btn1(btn2)]-padding-[btn2]-padding-|";
NSString * vflb = @"V:|-padding-[btn1(btn3)]-padding-[btn3]-padding-|";
NSString * vflc = @"V:|-padding-[btn2(btn3)]-padding-[btn3]-padding-|";
NSString * vfld = @"|-padding-[btn3]-padding-|";
dict中使用NSDictionary的一个宏来定义要约束的view
metrics放入定义的间距尺寸
dict和metrics相当于vfl中的名称与对象和数值的映射
“|”表示superView(不写H/V就表示横向),“-”表示连接符,padding表示已经定义的20.0f宽度,方括号表示view,圆括号表示尺寸数值。支持大小等于。或者另一个view
解释下vfla表示的意思 btn1距离superview左边距20,跟btn2左右间距20,btn2距离右边距20,btn1和btn2宽度相同
vflb表示的意思 btn1距离superview上边距20,跟btn3的上下间距20,btn3距离下边距20,btn1和btn3高度相同
剩下的vflc和vfld意思相近
创建完成后添加到view上
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:vfla options:0 metrics:metrics views:dict]];
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:vflb options:0 metrics:metrics views:dict]];
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:vflc options:0 metrics:metrics views:dict]];
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:vfld options:0 metrics:metrics views:dict]];
效果等同于xib和api创建的。
注意:在添加约束到view上时,遵循以下规则:
1.对于两个同层级view(在同一个superView)之间的约束关系,添加到他们的父view上
2.对于两个不同层级view(不在同一个superView)之间的约束关系,添加到他们最近的共同父view上
3.对于有层次关系的两个view之间的约束关系,添加到层次较高的父view上
2.对于两个不同层级view(不在同一个superView)之间的约束关系,添加到他们最近的共同父view上
3.对于有层次关系的两个view之间的约束关系,添加到层次较高的父view上
可以通过-setNeedsUpdateConstraints和-layoutIfNeeded两个方法来刷新约束的改变,使UIView重新布局。
个人使用感觉还是使用xib来添加简单快捷直观。