NSLayoutConstraint使用
使用很久的Masonry,但是对其原理不是很了解,大概看了一下,是基于NSLayoutConstraint的一个框架。今天就先看下NSLayoutConstraint的使用
NSLayoutConstraint的使用方式
+ (NSArray<NSLayoutConstraint *> *)constraintsWithVisualFormat:(NSString *)format options:(NSLayoutFormatOptions)opts metrics:(nullable NSDictionary<NSString *, id> *)metrics views:(NSDictionary<NSString *, id> *)views API_AVAILABLE(macos(10.7), ios(6.0), tvos(9.0));
+ (instancetype)constraintWithItem:(id)view1 attribute:(NSLayoutAttribute)attr1 relatedBy:(NSLayoutRelation)relation toItem:(nullable id)view2 attribute:(NSLayoutAttribute)attr2 multiplier:(CGFloat)multiplier constant:(CGFloat)c API_AVAILABLE(macos(10.7), ios(6.0), tvos(9.0));
一、constraintWithItem方式
直接上代码
UIView *superView = [[UIView alloc]initWithFrame:CGRectMake(30, 200, SCREEN_WIDTH - 60, 300)];
superView.backgroundColor = [UIColor lightGrayColor];
[self.view addSubview:superView];
UIView *subView = [[UIView alloc]init];
subView.backgroundColor = [UIColor yellowColor];
subView.frame = CGRectMake(0, 0, 100, 100);
/**
添加约束之前,需要将视图添加到父视图上;
*/
[self.view addSubview:subView];
/**
当使用autolayout布局是时,需要将视图的translatesAutoresizingMaskIntoConstraints属性设置为NO,不设置的话约束白加
*/
subView.translatesAutoresizingMaskIntoConstraints = NO;
/**
七个参数
1、要约束的视图view1
2、约束类型attr1,宽,高,中心,上,下,左右
3、约束方式,等于,小于等于。。。
4、约束参照视图view2
5、参照视图的参照属性attr2,上下左右。。。
6、乘数multiplier,倍数
7、约束值constant。
约束结果:view1.attr1 等于(约束方式) view2.attr2*multiplier +constant
*/
NSLayoutConstraint *constraint = [NSLayoutConstraint constraintWithItem:subView attribute:(NSLayoutAttributeTop) relatedBy:(NSLayoutRelationEqual) toItem:superView attribute:(NSLayoutAttributeBottom) multiplier:1 constant:30];
NSLayoutConstraint *constraint1 = [NSLayoutConstraint constraintWithItem:subView attribute:(NSLayoutAttributeLeft) relatedBy:(NSLayoutRelationEqual) toItem:superView attribute:(NSLayoutAttributeLeft) multiplier:1 constant:30];
NSLayoutConstraint *constraint2 = [NSLayoutConstraint constraintWithItem:subView attribute:(NSLayoutAttributeWidth) relatedBy:(NSLayoutRelationEqual) toItem:nil attribute:NSLayoutAttributeWidth multiplier:1 constant:50];
NSLayoutConstraint *constraint3 = [NSLayoutConstraint constraintWithItem:subView attribute:(NSLayoutAttributeHeight) relatedBy:(NSLayoutRelationEqual) toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1 constant:50];
/**
约束添加到哪个视图
1、自身约束。不需要依赖其他视图,如宽高数值,view2 = null,attr2 = NSLayoutAttributeNotAnAttribute。约束添加到view1上
2、相对父视图约束。约束添加到层级相对更高的视图上。
3、相对兄弟视图约束。约束添加到兄弟视图共同的父视图上 (别说面试造航母了, 这不就是是两个链表的第一个公共节点面试题应用场景)
View+MASAdditions 类中的mas_closestCommonSuperview方法便是找父视图
*/
[self.view addConstraint:constraint];
[self.view addConstraint:constraint1];
[subView addConstraint:constraint2];
[subView addConstraint:constraint3];
这种方式的关键点
1、设置translatesAutoresizingMaskIntoConstraints 为NO
关闭该属性,否则写布局代码等于写个空气
2、NSLayoutConstraint的创建
创建需要七个参数
- 指定要约束的视图view1
- 约束类型attr1,宽、高、左、右、上、下...
- 约束方式,等于、小于等于...
- 约束参照视图view2.如果设置具体宽高数据,可以传空
- 参照视图的参照属性attr2, view2为空时传NSLayoutAttributeNotAnAttribute,传其他的也一样
- 乘数multiplier,倍数
- 约束值constant。
约束结果:view1.attr1 等于(约束方式) view2.attr2*multiplier +constant
3、比较重要的是约束添加到哪个视图
- 自身约束。不需要依赖其他视图,如宽高数值,view2 = null,attr2 = NSLayoutAttributeNotAnAttribute。约束添加到view1上
- 相对父视图约束。约束添加到层级相对更高的视图上。
- 相对兄弟视图约束。约束添加到兄弟视图共同的父视图上
- 别说面试造航母了, 这不就是是两个链表的第一个公共节点面试题应用场景
- Masonry中View+MASAdditions 类中的mas_closestCommonSuperview方法便是找父视图,但是实现方式有点low,不过影响不大,依然是很优秀的框架
相关参数说明
NSLayoutAttribute类型
NSLayoutAttributeLeft 视图的左边
NSLayoutAttributeRight 视图的右边
NSLayoutAttributeTop 视图的上边
NSLayoutAttributeBottom 视图的下边
NSLayoutAttributeLeading 视图的前边
NSLayoutAttributeTrailing 视图的后边
NSLayoutAttributeWidth 视图的宽度
NSLayoutAttributeHeight 视图的高度
NSLayoutAttributeCenterX 视图的中点的X值
NSLayoutAttributeCenterY 视图中点的Y值
NSLayoutAttributeBaseline 视图的基准线
NSLayoutAttributeNotAnAttribute 无属性
3.NSLayoutRelation的类型:
NSLayoutRelationLessThanOrEqual 视图关系小于或等于
NSLayoutRelationEqual 视图关系等于
NSLayoutRelationGreaterThanOrEqual 视图关系大于或等于
二、constraintsWithVisualFormat方式
还是先上代码
UIView *view1 = [[UIView alloc]init];
view1.backgroundColor = [UIColor yellowColor];
view1.translatesAutoresizingMaskIntoConstraints = NO;
[superView addSubview:view1];
UIView *view2 = [[UIView alloc]init];
view2.backgroundColor = [UIColor yellowColor];
view2.translatesAutoresizingMaskIntoConstraints = NO;
[superView addSubview:view2];
UIView *view3 = [[UIView alloc]init];
view3.backgroundColor = [UIColor yellowColor];
view3.translatesAutoresizingMaskIntoConstraints = NO;
[superView addSubview:view3];
NSString *hVFL = @"H:|-space-[view1(==100)]-space1-[view2]-space-|";
NSString *hVFL1 = @"H:|-space-[view3]-space-|";
NSString *vVFL = @"V:|-space-[view1(==view3)]-space-[view3]-space-|";
NSString *vVFL1 = @"V:|-space-[view2(==view3)]-space-[view3]-space-|";
NSDictionary *metircs = @{@"space":@20,@"space1":@30};
NSDictionary *views = NSDictionaryOfVariableBindings(view1,view2,view3);
NSArray *hconstraint = [NSLayoutConstraint constraintsWithVisualFormat:hVFL options:NSLayoutFormatDirectionLeadingToTrailing metrics:metircs views:views];
NSArray *hconstraint1 = [NSLayoutConstraint constraintsWithVisualFormat:hVFL1 options:NSLayoutFormatDirectionLeadingToTrailing metrics:metircs views:views];
NSArray *vconstraint = [NSLayoutConstraint constraintsWithVisualFormat:vVFL options:NSLayoutFormatDirectionLeadingToTrailing metrics:metircs views:views];
NSArray *vconstraint1 = [NSLayoutConstraint constraintsWithVisualFormat:vVFL1 options:NSLayoutFormatDirectionLeadingToTrailing metrics:metircs views:views];
//添加约束
[superView addConstraints:hconstraint];
[superView addConstraints:hconstraint1];
[superView addConstraints:vconstraint];
[superView addConstraints:vconstraint1];
这种方式要说的有
1、设置translatesAutoresizingMaskIntoConstraints 为NO
关闭该属性,否则写布局代码等于写个空气
2、Constraints的创建
使用VFL格式化的字符串
指定VFL中所有对象的布局属性和方向
度量或者指标的字典,字典里面有相关的键值对来控制相关的度量指标,通过key获取;
指定约束的视图:一个或多个。
3、VFL语言的规则
- "H" 表示水平方向,"V"表示垂直方向;
- "|" 表示superview的边界;
- "[]" 表示view,"()"表示尺寸,它们可以多个条件组合,中间使用逗号分隔,举例:[view(>=70, <=100)];
- "-" 表示间隙;
- "@"表示优先级。举例:V:|-50@750-[view(55)]