IOS开发笔记之AutoLayout及VFL探索

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上

可以通过-setNeedsUpdateConstraints和-layoutIfNeeded两个方法来刷新约束的改变,使UIView重新布局。
个人使用感觉还是使用xib来添加简单快捷直观。




  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值