添加约束到相应的 View 上。
- (void)addConstraint:(NSLayoutConstraint *)constraint;
- (void)addConstraints:(NSArray<__kindof NSLayoutConstraint *> *)constraints;
obj1.property1 =(obj2.property2 * multiplier)+ constant value
/**
view1 :要约束的控件
attr1 :约束的类型(做怎样的约束)
relation :与参照控件之间的关系
view2 :参照的控件
attr2 :约束的类型(做怎样的约束)
multiplier :乘数
c :常量
*/
+ (instancetype)constraintWithItem:(id)view1 attribute:(NSLayoutAttribute)attr1 relatedBy:(NSLayoutRelation)relation toItem:(id)view2 attribute:(NSLayoutAttribute)attr2 multiplier:(CGFloat)multiplier constant:(CGFloat)c;
- (void)testAutolayout1 {
UIView *redV = [[UIView alloc] init];
redV.backgroundColor = [UIColor redColor];
redV.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addSubview:redV];
/**
view1 :要约束的控件
attr1 :约束的类型(做怎样的约束)
relation :与参照控件之间的关系
view2 :参照的控件
attr2 :约束的类型(做怎样的约束)
multiplier :乘数
c :常量
*/
/// 左间距100:
NSLayoutConstraint *consLeft = [NSLayoutConstraint constraintWithItem:redV attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeLeft multiplier:1.0 constant:100];
[self.view addConstraint:consLeft];
/// 上间距200:
NSLayoutConstraint *consTop = [NSLayoutConstraint constraintWithItem:redV attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeTop multiplier:1.0 constant:200];
[self.view addConstraint:consTop];
/// 宽150:
NSLayoutConstraint *consWidth = [NSLayoutConstraint constraintWithItem:redV attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeWidth multiplier:1.0 constant:150];
[redV addConstraint:consWidth];
/// 高64:
NSLayoutConstraint *consHeight = [NSLayoutConstraint constraintWithItem:redV attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeHeight multiplier:1.0 constant:64];
[redV addConstraint:consHeight];
}
UIView *blueV = [[UIView alloc] init];
blueV.backgroundColor = [UIColor blueColor];
blueV.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addSubview:blueV];
/// 和 redV 右间距为0
NSLayoutConstraint *b_consRight = [NSLayoutConstraint constraintWithItem:blueV attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:redV attribute:NSLayoutAttributeRight multiplier:1.0 constant:0.0];
[self.view addConstraint:b_consRight];
/// 和 redV 等高
NSLayoutConstraint *b_consHeight = [NSLayoutConstraint constraintWithItem:blueV attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:redV attribute:NSLayoutAttributeHeight multiplier:1.0 constant:0.0];
[self.view addConstraint:b_consHeight];
/// 宽度是 redV 的一半
NSLayoutConstraint *b_consWidth = [NSLayoutConstraint constraintWithItem:blueV attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:redV attribute:NSLayoutAttributeWidth multiplier:0.5 constant:0.0];
[self.view addConstraint:b_consWidth];
/// 顶部距离 redV 20
NSLayoutConstraint *b_consTop = [NSLayoutConstraint constraintWithItem:blueV attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:redV attribute:NSLayoutAttributeBottom multiplier:1.0 constant:20.0];
[self.view addConstraint:b_consTop];
最终效果:
在创建约束之后,需要将其添加到作用的view上。
在添加时要注意目标view需要遵循以下规则:
VFL全称是Visual Format Language,翻译过来是“可视化格式语言”,是苹果公司为了简化Autolayout的编码而推出的抽象语言。
/*
format :VFL语句
opts :约束类型
metrics :VFL语句中用到的具体数值
views :VFL语句中用到的控件
*/
+ (NSArray<__kindof NSLayoutConstraint *> *)constraintsWithVisualFormat:(NSString *)format options:(NSLayoutFormatOptions)opts metrics:(NSDictionary<NSString *,id> *)metrics views:(NSDictionary<NSString *,id> *)views;
@{@"redV" : redV}
等价于 NSDictionaryOfVariableBindings(redV)
NSDictionary *views =
NSDictionaryOfVariableBindings(blueView, redView);
NSArray *conts2 =
[NSLayoutConstraint constraintsWithVisualFormat:
@"V:[blueView(==blueHeight)]-margin-|" options:0 metrics:
@{@"blueHeight" : @40, @"margin" : @20} views:views];
水平方向 H:
垂直方向 V:
Views [view]
SuperView |
关系 >=,==,<=
空间,间隙 -
优先级 @value
水平方向距离左边距100,宽度200
垂直方向距离顶部200,高度64
水平方向redV 宽度72,blueV 宽度50,他们之间间距12
水平方向redV宽度大于等于60,优先级为700 (优先级最大1000)
竖直方向上,先有一个redBox,其下方紧接一个高度等于redBox高度的yellowBox
水平方向上,Find距离父view左边缘默认间隔宽度,之后是FindNext距离Find间隔默认宽度;再之后是宽度不小于20的FindField,它和FindNext以及父view右边缘的间距都是默认宽度。(竖线“|” 表示superview的边缘)
创建这种字符串时需要注意一下几点:
* H:和V:每次都使用一个。
* 视图变量名出现在方括号中,例如[view]。
* 字符串中顺序是按照从顶到底,从左到右
* 视图间隔以数字常量出现,例如-10-。
* |表示父视图
表达布局约束的规则可以使用一些简单的数学术语,如下表
类型 | 描述 | 值 |
---|---|---|
属性 | 视图位置 | NSLayoutAttributeLeft, NSLayoutAttributeRight, NSLayoutAttributeTop, NSLayoutAttributeBottom |
属性 | 视图前面后面 | NSLayoutAttributeLeading, NSLayoutAttributeTrailing |
属性 | 视图的宽度和高度 | NSLayoutAttributeWidth, NSLayoutAttributeHeight |
属性 | 视图中心 | NSLayoutAttributeCenterX, NSLayoutAttributeCenterY |
属性 | 视图的基线,在视图底部上方放置文字的地方 | NSLayoutAttributeBaseline |
属性 | 占位符,在与另一个约束的关系中没有用到某个属性时可以使用占位符 | NSLayoutAttributeNotAnAttribute |
关系 | 允许将属性通过等式和不等式相互关联 | NSLayoutRelationLessThanOrEqual, NSLayoutRelationEqual, NSLayoutRelationGreaterThanOrEqual |
数学运算 | 每个约束的乘数和相加性常数 | CGFloat值 |
- (void)testVFL {
UIView *redV = [[UIView alloc] init];
redV.backgroundColor = [UIColor redColor];
redV.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addSubview:redV];
UIView *blueV = [[UIView alloc] init];
blueV.backgroundColor = [UIColor blueColor];
blueV.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addSubview:blueV];
/*
format :VFL语句
opts :约束类型
metrics :VFL语句中用到的具体数值
views :VFL语句中用到的控件
*/
//水平方向 redV 左右间距为20
NSArray *cons1 = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|-20-[redV]-20-|" options:0 metrics:nil views:@{@"redV":redV}];
[self.view addConstraints:cons1];
//垂直方法redV距离顶部 100, redV 高度为64, blueV顶部距离redV 100 像素, blueV的高度等于redV
NSArray *cons2 = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|-margin-[redV(64)]-margin-[blueV(==redV)]" options:NSLayoutFormatAlignAllRight metrics:@{@"margin" : @100} views:NSDictionaryOfVariableBindings(redV,blueV)];
[self.view addConstraints:cons2];
NSLayoutConstraint *cons = [NSLayoutConstraint constraintWithItem:blueV attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:redV attribute:NSLayoutAttributeWidth multiplier:0.5 constant:0.0];
[self.view addConstraint:cons];
}
运行结果: