首页 > 代码库 > 【iOS开发-113】在storyboard上用AutoLayout,纯代码实现AutoLayout布局方法以及简单动画

【iOS开发-113】在storyboard上用AutoLayout,纯代码实现AutoLayout布局方法以及简单动画

(1)在storyboard中使用AutoLayout。这个AutoLayout和autoResizing是冲突的,只能选其一。

——不同级的控件的相互约束是添加在高层级上。

——同级别的控件的相互约束是添加在它们的父控件上。

——不同分支控件的相互约束是添加在它们向上追溯到的第一个共同父控件。

这3条规则在代码创建时有用。利用storyboard时系统自动帮我们添加好了。

技术分享


(2)用代码实现AutoLayout。步骤就是先创建布局约束对象,然后把这个对象添加到需要约束的控件中。

——需要先禁止需要约束的控件的autoresizing功能。

——添加约束对象之前,得保证该控件已经添加到各自的父控件中。

- (void)viewDidLoad {
    [super viewDidLoad];
    //保证需要约束的控件已有父控件
    UIView *blueView=[[UIView alloc]init];
    blueView.backgroundColor=[UIColor blueColor];
    [self.view addSubview:blueView];
    
    //关闭需要约束的控件的autoresizing
    blueView.translatesAutoresizingMaskIntoConstraints=NO;
    
    //定义约束对象,并添加(注意添加到哪里),宽高100,居中
    NSLayoutConstraint *width=[NSLayoutConstraint constraintWithItem:blueView attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0 constant:100];
    [blueView addConstraint:width];
    
    NSLayoutConstraint *height=[NSLayoutConstraint constraintWithItem:blueView attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0 constant:100];
    [blueView addConstraint:height];
    
    NSLayoutConstraint *centerX=[NSLayoutConstraint constraintWithItem:blueView attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeCenterX multiplier:1.0 constant:0];
    [self.view addConstraint:centerX];
    
    NSLayoutConstraint *centerY=[NSLayoutConstraint constraintWithItem:blueView attribute:NSLayoutAttributeCenterY relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeCenterY multiplier:1.0 constant:0];
    [self.view addConstraint:centerY];
}

(3)两个控件互相约束的代码,和上面单个控件的写法一样,只不过需要注意的是:控件是相对于谁计算的;约束添加在自己身上还是父控件上等。

技术分享

- (void)viewDidLoad {
    [super viewDidLoad];
    //保证需要约束的控件已有父控件
    UIView *blueView=[[UIView alloc]init];
    blueView.backgroundColor=[UIColor blueColor];
    [self.view addSubview:blueView];
    
    UIView *redView=[[UIView alloc]init];
    redView.backgroundColor=[UIColor redColor];
    [self.view addSubview:redView];
    
    //关闭需要约束的控件的autoresizing
    blueView.translatesAutoresizingMaskIntoConstraints=NO;
    redView.translatesAutoresizingMaskIntoConstraints=NO;
    
    //先调整blueView
    NSLayoutConstraint *height=[NSLayoutConstraint constraintWithItem:blueView attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0 constant:40];
    [blueView addConstraint:height];
    
    NSLayoutConstraint *left=[NSLayoutConstraint constraintWithItem:blueView attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeLeft multiplier:1.0 constant:20];
    [self.view addConstraint:left];
    //注意-20
    NSLayoutConstraint *right=[NSLayoutConstraint constraintWithItem:blueView attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeRight multiplier:1.0 constant:-20];
    [self.view addConstraint:right];
    
    NSLayoutConstraint *top=[NSLayoutConstraint constraintWithItem:blueView attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeTop multiplier:1.0 constant:20];
    [self.view addConstraint:top];
    
    //调整redView
    NSLayoutConstraint *heightR=[NSLayoutConstraint constraintWithItem:redView attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:blueView attribute:NSLayoutAttributeHeight multiplier:1.0 constant:0];
    [self.view addConstraint:heightR];
    
    NSLayoutConstraint *widthR=[NSLayoutConstraint constraintWithItem:redView attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:blueView attribute:NSLayoutAttributeWidth multiplier:0.5 constant:0];
    [self.view addConstraint:widthR];
    
    NSLayoutConstraint *rightR=[NSLayoutConstraint constraintWithItem:redView attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:blueView attribute:NSLayoutAttributeRight multiplier:1.0 constant:0];
    [self.view addConstraint:rightR];
    //注意redView的top是相对于blueView的bottom定位的
    NSLayoutConstraint *topR=[NSLayoutConstraint constraintWithItem:redView attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:blueView attribute:NSLayoutAttributeBottom multiplier:1.0 constant:20];
    [self.view addConstraint:topR];
}

(4)利用VFL语言,即visual format language。

——控件需要用 [ ] 括起来

—— | 表示父控件的边界

——乘除法则使用不便,部分还需要使用constraintWithItem:辅助

技术分享

- (void)viewDidLoad {
    [super viewDidLoad];
    //保证需要约束的控件已有父控件
    UIView *blueView=[[UIView alloc]init];
    blueView.backgroundColor=[UIColor blueColor];
    [self.view addSubview:blueView];
    
    UIView *redView=[[UIView alloc]init];
    redView.backgroundColor=[UIColor redColor];
    [self.view addSubview:redView];
    
    //关闭需要约束的控件的autoresizing
    blueView.translatesAutoresizingMaskIntoConstraints=NO;
    redView.translatesAutoresizingMaskIntoConstraints=NO;
    
    //利用VFL语言,但是有的不能实现,比如宽度的倍数,因为不能用乘除
    NSArray *cons0=[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-20-[blueView]-20-|" options:0 metrics:nil views:@{@"blueView":blueView}];
    [self.view addConstraints:cons0];
    
    NSArray *cons1=[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-20-[blueView(40)]-20-[redView(==blueView)]" options:NSLayoutFormatAlignAllRight metrics:nil views:@{@"blueView":blueView,@"redView":redView}];
    [self.view addConstraints:cons1];
    
    NSArray *cons2=[NSLayoutConstraint constraintsWithVisualFormat:@"H:[redView(==blueView)]" options:0 metrics:nil views:@{@"blueView":blueView,@"redView":redView}];
    [self.view addConstraints:cons2];
}

——其中option的选项,是用在有两个控件,需要对齐时用,可以用 | 符号使用多个。

——其中metrics一个存放占位符号和值得字典。比如如下,当然,我们可以另写一个NSDictionary字典来存放:

NSArray *cons0=[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-margin-[blueView]-margin-|" options:0 metrics:@{@"margin":@20} views:@{@"blueView":blueView}];

——其中views可以有简便的写法,如下,用NSDictionaryOfVariableBindings()创建一个键值对。

NSArray *cons0=[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-margin-[blueView]-margin-|" options:0 metrics:@{@"margin":@20} views:NSDictionaryOfVariableBindings(blueView,redView)];

(5)AutoLayout可以让Label实现根据内容多少自动增加高度。当然label的行数需要设置为0,即可换行。


(6)AutoLayout也可以做动画,即改变约束的值。

——动画效果还需要UIView的animationWithDuration配合。需要注意的是,此处需要先修改好约束值,然后在动画方法中调用布局方法即layoutIfNeeded。

——其中只有常量constant可以修改,其他的基本都是readonly只读的,不能修改。

#import "ViewController.h"

@interface ViewController ()
@property(nonatomic,strong) NSLayoutConstraint *con3;
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    .....
    NSLayoutConstraint *con3=[NSLayoutConstraint constraintWithItem:redView attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:blueView attribute:NSLayoutAttributeWidth multiplier:0.5 constant:0];
    [self.view addConstraint:con3];
    self.con3=con3;
}

-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{
    self.con3.constant=100;
    [UIView animateWithDuration:1.0 animations:^{
        [self.view layoutIfNeeded];
    }];
}

【iOS开发-113】在storyboard上用AutoLayout,纯代码实现AutoLayout布局方法以及简单动画