前言:
1、使用VFL布局前,相关的View要关闭系统的自定义布局;
view.translatesAutoresizingMaskIntoConstraints = NO;
2、VFL字符串不可以有空格;
VFL API
/*
format参数: VFL字符串,形如 @"V:|-topMargin-[view1(50.0)]-20-[view2(50.0)]";
option参数: 约束类型 opts参数是个枚举值, 主要用来布局view的对齐方式;
metrics参数: 替换VFL字符串中的变量字典, 如果这么写: @{@"topMargin":@10} 则VFL布局中可以替换成下面的写法: @"V:|-10-[view1(50.0)]-20-[view2(50.0)]" 其实就是替换字符串中的变量使用;
views参数: VFL语句中用到的控件 views参数是一个字典,里面可以存储一些数值, 这样存储之后就可以在VFL字符串中调用了 为了方便苹果官方提供了一个宏,传入相关的view变量名,返回可以直接使用的dictionary*/
+ (NSArray<__kindof NSLayoutConstraint *> *)constraintsWithVisualFormat:(NSString *)format
options:(NSLayoutFormatOptions)opts
metrics:(nullable NSDictionary<NSString *,id> *)metrics
views:(NSDictionary<NSString *, id> *)views;
//views示例
NSDictionaryOfVariableBindings(v1, v2, v3)
//等价于
[NSDictionary dictionaryWithObjectsAndKeys:v1, @”v1”, v2, @”v2”, v3, @”v3”, nil];
/*和此方法搭配可以实现更复杂的布局
view1.attribute1 = view2.attribute2 × multiplier + constant
view1.attribute1 >= view2.attribute2 × multiplier + constant
view1.attribute1 <= view2.attribute2 × multiplier + constant
*/
+ (instancetype)constraintWithItem:(id)view1
attribute:(NSLayoutAttribute)attr1
relatedBy:(NSLayoutRelation)relation
toItem:(nullable id)view2
attribute:(NSLayoutAttribute)attr2
multiplier:(CGFloat)multiplier
constant:(CGFloat)c
VFL布局符号
| : 表示父视图
- : 表示距离(默认两个子视图之间的值是8,与父视图之间的值是16)
[] : 表示视图 (每个视图必须用[]包裹起来,否则语法错误)
() : 定义控件的宽/高,可以在metrics中指定
V : 表示垂直
H : 表示水平
= : 表示视图间距、宽度和高度必须大于或等于某个值
<= : 表示视图间距、宽度和高度必须小宇或等于某个值
== : 表示视图间距、宽度或者高度必须等于某个值
@ : 约束的优先级 取值范围为0~1000(250、750、1000)
VFL布局符号用法
|-[view]-|: 视图处在父视图的左右边缘内(左右会有默认边距)
|-[view] : 视图处在父视图的左边缘
|[view] : 视图和父视图左边对齐
V:[view(20)] : 设置视图的高度
H:[view(20.)] : 设置视图的宽度
|-10.0-[view]-10.0-|: 表示离父视图 左右间距 10
|-[view(view1)]-[view1]-| : View和view1视图宽度一样,并且在父视图内
|-[view(view1)][view1]-| : View和view1视图宽度一样,并且在父视图内,两视图间隔为0
V:|-padding-[imageView]->=0-[button]-padding| : 表示离父视图的距离为Padding,这两个视图间距必须大于或等于0并且距离底部父视图为padding。此时必须对 metrics参数赋值eg. metrics:@{@"topMargin":@100};
[wideView(>=60@700)] :视图的宽度为至少为60 优先级为700
[view(>=60,<=90)] :视图约束多个条件之间用","连接并且之间不能有空格
最后要注意, H可以忽略, 默认为水平布局 , V必须要写!!!
VFL Demo
- (void)viewSafeAreaInsetsDidChange {
//安全高度
UIEdgeInsets safe_insets = self.view.safeAreaInsets;
CGFloat topMargin = safe_insets.top > 0 ? safe_insets.top : 60;
//创建3个view的对象
UIView *leftView = [[UIView alloc]init];
UIView *rightView = [[UIView alloc]init];
UIView *bottomView = [[UIView alloc]init];
//设置背景颜色
leftView.backgroundColor = [UIColor greenColor];
rightView.backgroundColor = [UIColor purpleColor];
bottomView.backgroundColor = [UIColor orangeColor];
//添加视图上显示
[self.view addSubview:leftView];
[self.view addSubview:rightView];
[self.view addSubview:bottomView];
//关闭系统的自定义布局
leftView.translatesAutoresizingMaskIntoConstraints = NO;
rightView.translatesAutoresizingMaskIntoConstraints = NO;
bottomView.translatesAutoresizingMaskIntoConstraints = NO;
//创建VFL约束字符串
NSString *h_VFL = @"H:|-[leftView(==rightView)]-margin-[rightView]-space-|";
NSString *h_VFL1 = @"H:[bottomView(==leftView)]";
NSString *v_VFL = @"V:|-topMargin-[leftView(==bottomView)]-space-[bottomView]-space-|";
NSString *v_VFL1 = @"V:|-topMargin-[rightView(==bottomView)]";
//创建键值映射
NSDictionary *metircs = @{@"space":@20,@"margin":@30,@"topMargin":@(topMargin)};
NSDictionary *views = NSDictionaryOfVariableBindings(leftView,rightView,bottomView);
//创建约束
NSArray *h_constraint = [NSLayoutConstraint constraintsWithVisualFormat:h_VFL options:0 metrics:metircs views:views];
NSArray *h_constraint1 = [NSLayoutConstraint constraintsWithVisualFormat:h_VFL1 options:0 metrics:metircs views:views];
NSArray *v_constraint = [NSLayoutConstraint constraintsWithVisualFormat:v_VFL options:NSLayoutFormatDirectionLeadingToTrailing metrics:metircs views:views];
NSArray *v_constraint1 = [NSLayoutConstraint constraintsWithVisualFormat:v_VFL1 options:NSLayoutFormatDirectionLeadingToTrailing metrics:metircs views:views];
NSLayoutConstraint *center_x_constraint = [NSLayoutConstraint constraintWithItem:bottomView
attribute:NSLayoutAttributeCenterX
relatedBy:NSLayoutRelationEqual
toItem:self.view
attribute:NSLayoutAttributeCenterX
multiplier:1
constant:0];
//添加约束
[self.view addConstraints:h_constraint];
[self.view addConstraints:h_constraint1];
[self.view addConstraints:v_constraint];
[self.view addConstraints:v_constraint1];
[self.view addConstraint:center_x_constraint];
}
写在最后
Auto Layout Guide: Visual Format Language
iOS--NSLayoutConstraint
自动布局 VFL