第三章 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两者一样