-
NSLayoutConstraint,系统的布局类
/**
系统默认添加约束的方法,它是NSLayoutConstraint的类方法
@param view1 想要添加约束的控件
@param attr1 想要添加约束的方向
@param relation 传入与约束值的关系,大于、等于还是小于
@param view2 被参照对象
@param attr2 被参照对象所被参照的方向,如顶部、左边、右边等
@param multiplier 间距倍数关系
@param c 最终的差值
@return NSLayoutConstraint对象
*/
//+(instancetype)constraintWithItem:(id)view1
// attribute:(NSLayoutAttribute)attr1
// relatedBy:(NSLayoutRelation)relation
// toItem:(nullable id)view2
// attribute:(NSLayoutAttribute)attr2
// multiplier:(CGFloat)multiplier
// constant:(CGFloat)c
-(void)sysAutolayout{
/////////////////////////////////////////// red view ////////////////////////////////////////////////
UIView *redView = [[UIView alloc] init];
[self.view addSubview:redView];
redView.backgroundColor = [UIColor redColor];
//⚠️:一定要加上这句代码,否则添加的约束会有冲突
redView.translatesAutoresizingMaskIntoConstraints = NO;
//左边的约束
NSLayoutConstraint *redLeftCons = [NSLayoutConstraint constraintWithItem:redView
attribute:NSLayoutAttributeLeft
relatedBy:NSLayoutRelationEqual
toItem:self.view
attribute:NSLayoutAttributeLeft
multiplier:1
constant:20];
// [self.view addConstraint:redLeftCons];
redLeftCons.active = YES;//这是官方建议的方法
//底部的约束
NSLayoutConstraint *redBottomCons = [NSLayoutConstraint constraintWithItem:redView
attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual
toItem:self.view
attribute:NSLayoutAttributeBottom
multiplier:1
constant:-20];
//⚠️:只在没有参照控件时(即toItem为nil),约束才添加到自己身上,不然添加到父视图上
// [self.view addConstraint:redBottomCons];
redBottomCons.active = YES;
//宽度约束
//可以参照其他控件设置约束,如下:
// [NSLayoutConstraint constraintWithItem:redView
// attribute:NSLayoutAttributeWidth
// relatedBy:NSLayoutRelationEqual
// toItem:self.view
// attribute:NSLayoutAttributeWidth
// multiplier:0.5
// constant:0];
//也可以不参照其他控件
NSLayoutConstraint *redWidthCons = [NSLayoutConstraint constraintWithItem:redView
attribute:NSLayoutAttributeWidth
relatedBy:NSLayoutRelationEqual
toItem:nil
attribute:kNilOptions
multiplier:1.0
constant:50];
//这里没有参照控件,所以约束添加到自己身上
// [redView addConstraint:redWidthCons];
redWidthCons.active = YES;
//长度约束,同宽度约束
NSLayoutConstraint *redHeightCons = [NSLayoutConstraint constraintWithItem:redView
attribute:NSLayoutAttributeHeight
relatedBy:NSLayoutRelationEqual
toItem:nil
attribute:kNilOptions
multiplier:1.0
constant:40];
// [redView addConstraint:redHeightCons];
redHeightCons.active = YES;
/////////////////////////////////////////// blue view ////////////////////////////////////////////////
UIView *blueView = [[UIView alloc] init];
[self.view addSubview:blueView];
blueView.backgroundColor = [UIColor blueColor];
_blueView = blueView;
blueView.translatesAutoresizingMaskIntoConstraints = NO;
NSLayoutConstraint *blueLeftCons = [NSLayoutConstraint constraintWithItem:blueView
attribute:NSLayoutAttributeLeft
relatedBy:NSLayoutRelationEqual
toItem:redView
attribute:NSLayoutAttributeRight
multiplier:1
constant:10];
[self.view addConstraint:blueLeftCons];
NSLayoutConstraint *blueBottomCons = [NSLayoutConstraint constraintWithItem:blueView
attribute:NSLayoutAttributeBottom
relatedBy:NSLayoutRelationEqual
toItem:redView
attribute:NSLayoutAttributeBottom
multiplier:1
constant:0];
[self.view addConstraint:blueBottomCons];
NSLayoutConstraint *blueWidthCons = [NSLayoutConstraint constraintWithItem:blueView
attribute:NSLayoutAttributeWidth
relatedBy:NSLayoutRelationEqual
toItem:nil
attribute:kNilOptions
multiplier:1
constant:50];
[blueView addConstraint:blueWidthCons];
NSLayoutConstraint *blueHeightCons = [NSLayoutConstraint constraintWithItem:blueView
attribute:NSLayoutAttributeHeight
relatedBy:NSLayoutRelationEqual
toItem:nil
attribute:kNilOptions
multiplier:1
constant:50];
[blueView addConstraint:blueHeightCons];
/////////////////////////////////////////// yellow view ////////////////////////////////////////////////
UIView *yellowView = [[UIView alloc] init];
[self.view addSubview:yellowView];
yellowView.backgroundColor = [UIColor yellowColor];
yellowView.translatesAutoresizingMaskIntoConstraints = NO;
NSLayoutConstraint *yellowLeftCons = [NSLayoutConstraint constraintWithItem:yellowView
attribute:NSLayoutAttributeLeft
relatedBy:NSLayoutRelationEqual
toItem:blueView
attribute:NSLayoutAttributeRight
multiplier:1
constant:10];
[self.view addConstraint:yellowLeftCons];
NSLayoutConstraint *yellowBottomCons = [NSLayoutConstraint constraintWithItem:yellowView
attribute:NSLayoutAttributeBottom
relatedBy:NSLayoutRelationEqual
toItem:redView
attribute:NSLayoutAttributeBottom
multiplier:1
constant:0];
[self.view addConstraint:yellowBottomCons];
NSLayoutConstraint *yellowWidthCons = [NSLayoutConstraint constraintWithItem:yellowView
attribute:NSLayoutAttributeWidth
relatedBy:NSLayoutRelationEqual
toItem:nil
attribute:kNilOptions
multiplier:1
constant:50];
[yellowView addConstraint:yellowWidthCons];
NSLayoutConstraint *yellowHeightCons = [NSLayoutConstraint constraintWithItem:yellowView
attribute:NSLayoutAttributeHeight
relatedBy:NSLayoutRelationEqual
toItem:nil
attribute:kNilOptions
multiplier:1
constant:50];
[yellowView addConstraint:yellowHeightCons];
//低优先级的约束
NSLayoutConstraint *yellowLeftCons_1 = [NSLayoutConstraint constraintWithItem:yellowView
attribute:NSLayoutAttributeLeft
relatedBy:NSLayoutRelationEqual
toItem:redView
attribute:NSLayoutAttributeRight
multiplier:1
constant:10];
//优先级的范围时0-1000,默认是1000
//数字越大,优先级越高
//优先级相同时,会造成约束冲突
yellowLeftCons_1.priority = 250;//此时优先级低于yellowLeftCons,不执行
[self.view addConstraint:yellowLeftCons_1];
[self.view removeConstraint:yellowLeftCons_1];
}
- VFL
/**
VFL创建约束的API
@param format 传入某种格式构成的字符串,用以表达需要添加的约束,如@"H:|-margin-[redView(50)]"表示:水平方向上,redview与父控件左边缘保持"margin"间距,redview的宽度为50
@param opts 对齐方式,相对于format中所有视图的对齐约束,如果format只有一个view时,可以不设置
@param metrics 一般传入以间距为key的字典,如:@{@"margin":@20},key要与format参数里所填写的"margin"相同
@param views 传入约束中提到的view,也是字典,如:@{@"redView":redView},key要与format参数里所填写的"redView"相同
@return 返回约束的数组
*/
//+ (NSArray *)constraintsWithVisualFormat:(NSString *)format options:(NSLayoutFormatOptions)opts metrics:(NSDictionary *)metrics views:(NSDictionary *)views{}
//vfl是基于NSLayoutConstraint的一种自动布局方式
//format 语法:
//1.每句的前面都要加@"H:"或者@"V:",分别代表着水平和垂直方向
//2.@"|"代表着边界
//3.@"-"用来表示间隙,一般以这样的形式出现@"-20-",也可以先填写标示@"-margin-",之后通过metrics赋值
//4.@"[]"用来存放需要添加约束的view,想要直接设置宽高就这样[redView(50)]
//示例
//H:[cancelButton(72)]-12-[acceptButton(50)]
//cancelButton宽72,acceptButton宽50,它们之间间距12
//
//H:[wideView(>=60@700)]
//wideView宽度大于等于60point,该约束条件优先级为700(优先级最大值为1000,优先级越高的约束条件越先被满足)
//
//V:[redBox][yellowBox(==redBox)]
//垂直方向上,先有一个redBox,其下方紧接一个高度等于redBox高度的yellowBox
//
//H:|-10-[Find]-[FindNext]-[FindField(>=20)]-|
//水平方向上,Find距离父view左边缘间隔10,之后是FindNext距离Find间隔默认宽度;再之后是宽度不小于20的FindField,它和FindNext以及父view右边边缘的间距都是默认宽度。(竖线“|”表示superview的边缘)。
-(void)vflAutolayout{
UIView *redView = [[UIView alloc] init];
[self.view addSubview:redView];
redView.backgroundColor = [UIColor redColor];
redView.translatesAutoresizingMaskIntoConstraints = NO;
//这个方法会自动把传入的参数以字典的形式返回,字典的key就是其本身的名字
NSDictionary *redViewInfo = NSDictionaryOfVariableBindings(redView);
NSString *hFormat = @"H:|-margin-[redView(redWidth)]";
NSArray *hCons = [NSLayoutConstraint constraintsWithVisualFormat:hFormat
options:kNilOptions
metrics:@{@"margin":@20,@"redWidth":@50}
views:redViewInfo];
// [self.view addConstraints:hCons];
[NSLayoutConstraint activateConstraints:hCons];
NSString *vFormat = @"V:|-margin-[redView(redHeight)]";
NSArray *vCons = [NSLayoutConstraint constraintsWithVisualFormat:vFormat
options:kNilOptions
metrics:@{@"margin":@20,@"redHeight":@100}
views:redViewInfo];
// [self.view addConstraints:vCons];
[NSLayoutConstraint activateConstraints:vCons];
}
-(void)vflAutolayout_complex{
UIView *redView = [[UIView alloc] init];
[self.view addSubview:redView];
redView.backgroundColor = [UIColor redColor];
redView.translatesAutoresizingMaskIntoConstraints = NO;
UIView *blueView = [[UIView alloc] init];
[self.view addSubview:blueView];
blueView.backgroundColor = [UIColor blueColor];
_blueView = blueView;
blueView.translatesAutoresizingMaskIntoConstraints = NO;
UIView *yellowView = [[UIView alloc] init];
[self.view addSubview:yellowView];
yellowView.backgroundColor = [UIColor yellowColor];
yellowView.translatesAutoresizingMaskIntoConstraints = NO;
//////////////////////////////////////////////////////////////
//这个方法会自动把传入的参数以字典的形式返回,字典的key就是其本身的名字
NSDictionary *viewInfo = NSDictionaryOfVariableBindings(redView,blueView,yellowView);
NSDictionary *metrics = @{@"margin":@20};
NSString *hConsFormat = @"H:|-margin-[redView(50)]-margin-[blueView(==redView)]-margin-[yellowView(==redView)]";
NSArray *hCons = [NSLayoutConstraint constraintsWithVisualFormat:hConsFormat
options:NSLayoutFormatAlignAllTop | NSLayoutFormatAlignAllBottom
metrics:metrics
views:viewInfo];
[NSLayoutConstraint activateConstraints:hCons];
//设置约束的优先级,需要明确是哪个约束需要设置优先级
NSString *hConsFormat_1 = @"H:|-margin-[redView(50)]-margin@250-[yellowView(==redView)]";
NSArray *hCons_1 = [NSLayoutConstraint constraintsWithVisualFormat:hConsFormat_1 options:NSLayoutFormatAlignAllTop | NSLayoutFormatAlignAllBottom metrics:metrics views:viewInfo];
[NSLayoutConstraint activateConstraints:hCons_1];
NSString *vConsFormat = @"V:|-margin-[redView(50)]";
NSArray *vCons = [NSLayoutConstraint constraintsWithVisualFormat:vConsFormat
options:kNilOptions
metrics:metrics
views:viewInfo];
[NSLayoutConstraint activateConstraints:vCons];
}
- masonry
-(void)masonry_autolayout{
UIView *redView = [[UIView alloc] init];
[self.view addSubview:redView];
redView.backgroundColor = [UIColor redColor];
_redView = redView;
UIView *blueView = [[UIView alloc] init];
[self.view addSubview:blueView];
blueView.backgroundColor = [UIColor blueColor];
_blueView = blueView;
UIView *yellowView = [[UIView alloc] init];
[self.view addSubview:yellowView];
yellowView.backgroundColor = [UIColor yellowColor];
_yellowView = yellowView;
[redView mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.leading.equalTo(self.view).offset(20);
make.width.height.equalTo(@50);
}];
[blueView mas_makeConstraints:^(MASConstraintMaker *make) {
make.leading.mas_equalTo(redView.mas_trailing).offset(10);
make.top.width.height.equalTo(redView);
}];
// [yellowView mas_makeConstraints:^(MASConstraintMaker *make) {
// make.top.width.height.equalTo(redView);
// make.leading.mas_equalTo(blueView.mas_trailing).offset(10);
// make.leading.mas_equalTo(redView.mas_trailing).offset(10).priorityLow();
// }];
[yellowView mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.width.height.equalTo(redView);
self.leftCons = make.leading.mas_equalTo(blueView.mas_trailing).offset(10);
// make.leading.mas_equalTo(blueView.mas_trailing).offset(10);
}];
}
- 更新约束
-(void)update_masonry_layout{
_blueView.hidden = YES;
// [_yellowView mas_remakeConstraints:^(MASConstraintMaker *make) {
// make.top.width.height.equalTo(self.redView);
// make.leading.mas_equalTo(self.redView.mas_trailing).offset(10);
// }];
//mas_updateConstraints 所做的只是在原有约束的基础上添加约束,如果原来的约束中存在对应的约束就覆盖原约束
//如果原来的约束不存在对应的约束,并且有约束与新的约束相冲突,就需要先删除原约束
[self.leftCons uninstall];
[_yellowView mas_updateConstraints:^(MASConstraintMaker *make) {
make.leading.mas_equalTo(self.redView.mas_trailing).offset(10);
}];
}