第三章 Autolayout

代码实现自动布局

  • 使用代码创建控件,实现Autolayout的时候最好不要使用frame这个方法,很多时候会有问题
  • 添加约束的规则
    • 在创建约束之后,需要将其添加到作用的view上
    • 对于两个同层级的view约束关系,添加到他们的父view上
    • 对于两个不同层级的view之间的约束关系,添加到他们最近的共同父view上
  • 创建约束
+(instancetype)constraintWithItem:(id)view1 attribute:(NSLayoutAttribute)attr1 relatedBy:(NSLayoutRelation)relation toItem:(nullable id)view2 attribute:(NSLayoutAttribute)attr2 multiplier:(CGFloat)multiplier constant:(CGFloat)c;

view1:需要约束的控件

attr1:需要约束的类型,

relation:与参照控件之间的关系

view2:参照的控件

attr2:约束的类型(做怎样的约束)

multiplier:乘数

c:常亮

//
//  ViewController.m
//  JXAutolayout
//
//  Created by yuezuo on 16/4/15.
//  Copyright © 2016年 yuezuo. All rights reserved.
//

#import "ViewController.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    UIView * blueView = [[UIView alloc] init];
    blueView.backgroundColor = [UIColor blueColor];
    [self.view addSubview:blueView];

    // 这个属性会AutoresizingMask自动转换为Autolayout的约束,与自己的约束Yui有所冲突
    blueView.translatesAutoresizingMaskIntoConstraints = NO;

    // 添加宽度约束:300
    NSLayoutConstraint * widthConstraint = [NSLayoutConstraint constraintWithItem:blueView attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:0.0 constant:300];
    [blueView addConstraint:widthConstraint];

    // 添加高度约束:100
    NSLayoutConstraint * heightConstraint = [NSLayoutConstraint constraintWithItem:blueView attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:0.0 constant:100];
    [blueView addConstraint:heightConstraint];

    // 添加右边约束:blueView
    NSLayoutConstraint * rightConstraint = [NSLayoutConstraint constraintWithItem:blueView attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeRight multiplier:1.0 constant:-10];
    // 两个约束跟两个控件有关系,所以添加到父控件
    [self.view addConstraint:rightConstraint];

    // 添加底边约束:blueView
    NSLayoutConstraint * bottomConstraint = [NSLayoutConstraint constraintWithItem:blueView attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeBottom multiplier:1.0 constant:-10];
    // 两个约束跟两个控件有关系,所以添加到父控件
    [self.view addConstraint:bottomConstraint];

}


@end

这种添加约束的方式为单个约束对象的添加,过程比较麻烦,没有任何技术含量

  • 下面有一种批量添加约束的方式

    • VFL语言,是一种可视化格式语言,是苹果公司为了简化Autolayout的编码推出来的抽象语言
    • H:[cancelButton(72)]-12-[acceptButton(50)]

      表示在水平方向上有一个cancelButton按钮和一个acceptButton按钮。按钮长度为72,两个按钮中间的距离为12右边有一个接受按钮,按钮的长度为50

    • V:[cancelButton(72)]-12-[acceptButton(50)]

      效果同水平方向上一样

    • V:|-10-[cancelButton(72)]-12-[acceptButton(50)]-10-|

      代表关闭按钮距离左边屏幕有10的间距

  • 批量添加的代码

//
//  ViewController.m
//  Autolayout代码批量添加
//
//  Created by yuezuo on 16/4/15.
//  Copyright © 2016年 yuezuo. All rights reserved.
//

#import "ViewController.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    UIView * blueView = [[UIView alloc] init];
    blueView.backgroundColor = [UIColor blueColor];
    // 这个属性会AutoresizingMask自动转换为Autolayout的约束,与自己的约束Yui有所冲突
    blueView.translatesAutoresizingMaskIntoConstraints = NO;
    [self.view addSubview:blueView];


    // 添加约束 水平方向
    NSString * vfl = @"H:|-20-[blueView]-20-|";
//    NSDictionary * views = @{@"blueView":blueView};
    NSDictionary * views = NSDictionaryOfVariableBindings(blueView);
    NSArray * constraints = [NSLayoutConstraint constraintsWithVisualFormat:vfl options:kNilOptions metrics:nil views:views];
    [self.view addConstraints:constraints];

    // 添加约束 水平方向
    NSString * vfl2 = @"V:|-20-[blueView(20)]|";
    NSDictionary * views2 = @{@"blueView":blueView};
    NSArray * constraints2 = [NSLayoutConstraint constraintsWithVisualFormat:vfl2 options:kNilOptions metrics:nil views:views2];
    [self.view addConstraints:constraints2];
}

@end
NSDictionary * views = @{@"blueView":blueView};
NSDictionary * views = NSDictionaryOfVariableBindings(blueView);
两行代码锁表达的意思是一样的。

metrics:参数使用

 // 间距
    NSNumber * margin = @20;

    // 添加约束 水平方向
    NSString * vfl = @"H:|-margin-[blueView]-margin-|";
//    NSDictionary * views = @{@"blueView":blueView};
    NSDictionary * views = NSDictionaryOfVariableBindings(blueView);
    NSDictionary * mertrics = @{@"margin":margin};
    NSArray * constraints = [NSLayoutConstraint constraintsWithVisualFormat:vfl options:kNilOptions metrics:margin views:views];
    [self.view addConstraints:constraints];

三方框架 Masonry

  • 目前最流行的Autolayout第三方框架
  • 框架地址 Masonry

简介

//
//  ViewController.m
//  JXMasonry
//
//  Created by yuezuo on 16/4/15.
//  Copyright © 2016年 yuezuo. All rights reserved.
//

#import "ViewController.h"
#import "Masonry.h"
@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    UIView * blueView = [[UIView alloc] init];
    blueView.backgroundColor = [UIColor blueColor];
    [self.view addSubview:blueView];

    // 添加新的约束
    [blueView mas_makeConstraints:^(MASConstraintMaker *make) {
        // 在这个block里面利用make对象创建约束

        // 尺寸约束
        make.size.mas_equalTo(CGSizeMake(100, 100));
        // 位置约束:居中
        make.center.mas_equalTo(self.view);
    }];
}

@end

基本使用

// 这个方法用来添加新的约束
    [blueView mas_makeConstraints:^(MASConstraintMaker *make) {

    }];
// 这个方法会将以前的约束删除,添加新的约束
    [blueView mas_remakeConstraints:^(MASConstraintMaker *make) {

    }];
// 这个方法会覆盖以前的某些特定的约束
    [blueView mas_updateConstraints:^(MASConstraintMaker *make) {

    }];
  • 代码中使用
- (void)test2 {
    UIView * blueView = [[UIView alloc] init];
    blueView.backgroundColor = [UIColor blueColor];
    [self.view addSubview:blueView];

    // 尺寸限制:100*100

    // 这个方法用来添加新的约束
    [blueView mas_makeConstraints:^(MASConstraintMaker *make) {
        // 宽度约束
        make.width.equalTo(@100);
        // 高度约束
        make.height.equalTo(@100);
        // 右边
        make.right.equalTo(self.view.mas_right).offset(-100);
        // 底部
        make.bottom.equalTo(self.view.mas_bottom).offset(-200);
    }];
}

这个使用中直接使用equalTo之后的数据需要自己包装

- (void)test3 {
    UIView * blueView = [[UIView alloc] init];
    blueView.backgroundColor = [UIColor blueColor];
    [self.view addSubview:blueView];

    // 尺寸限制:100*100

    // 这个方法用来添加新的约束
    [blueView mas_makeConstraints:^(MASConstraintMaker *make) {

        // 约束宽度高度 mas_equalTo(这里面的数据不需要包装)
        make.width.and.height.mas_equalTo(100);
        make.right.and.bottom.mas_equalTo(-200);
    }];
}

这里面的mas_equalTo()之后的数据不需要包装,同时其中and的语法是为了增加代码的可读性,返回的是self

- (void)test4 {
    UIView * blueView = [[UIView alloc] init];
    blueView.backgroundColor = [UIColor blueColor];
    [self.view addSubview:blueView];

    // 尺寸限制:100*100

    // 这个方法用来添加新的约束
    [blueView mas_makeConstraints:^(MASConstraintMaker *make) {

        make.size.mas_equalTo(100);
        // blueView的右边等于父控件的右边偏移-200
        make.right.equalTo(self.view.mas_right).offset(-200);
        make.top.equalTo(self.view.mas_top).offset(200);
    }];
}
  • make.right.equalTo(self.view.mas_right).offset(-200);
    // 这句代码的意思就是表达:这个控件的控件的右边等于父控件的右边偏移-200
    

masnory的其他用法

- (void)test5 {
    UIView * blueView = [[UIView alloc] init];
    blueView.backgroundColor = [UIColor blueColor];
    [self.view addSubview:blueView];

    // 居中
    [blueView mas_makeConstraints:^(MASConstraintMaker *make) {

        make.size.mas_equalTo(self.view).multipliedBy(0.5);
        make.center.mas_equalTo(self.view);
        //        make.centerX.mas_equalTo(self.view);
        //        make.centerY.mas_equalTo(self.view);
    }];
}

masnory的一些使用总结

  • mas_equalTo 和equalTo

    • 默认情况下mas_equalTo有包装功能,比如20,自动包装成@20
    • equalTo没有自动包装功能
  • 如果添加了下面的宏,那么mas_equalTo 和equalTo就没有区别了

    • define MAS_SHORTHAND_GLOBALS

      注意:这个宏一定要添加到#import "Masonry.h"前面

  • mas_width和width

    • 默认情况下width 是make对象的一个属性,用来添加宽度属性约束用的,表示对宽度进行约束
    • mas_width是一个属性值,用来当做equalTo的参数,表示某个控件的宽度属性
    • 如果添加了宏 #define MAS_SHORTHAND两者一样

results matching ""

    No results matching ""