约束
,参照
位置
,尺寸
位置
与尺寸
,就足够了约束
就是对控件的大小或者位置进行约束,参照
就是以某个控件的位置进行约束
,其实这两者没有明确的分别,它们都可以对控件的位置
与尺寸
起到作用。位置
,尺寸
,Autolayout就是拿来干这个用的,所以我后面的例子都以UIView为例位置
,尺寸
的设置吧/**
* 这个是系统默认添加约束的方法,它是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:(id)view2 attribute:(NSLayoutAttribute)attr2 multiplier:(CGFloat)multiplier constant:(CGFloat)c
//一部分NSLayoutAttribute枚举值
NSLayoutAttributeLeft = 1,//控件左边
NSLayoutAttributeRight,//控件右边
NSLayoutAttributeTop,
NSLayoutAttributeBottom,
NSLayoutAttributeLeading,//控件左边
NSLayoutAttributeTrailing,//控件右边
NSLayoutAttributeWidth,//控件的宽
NSLayoutAttributeHeight,//控件的高
NSLayoutAttributeCenterX,//竖直方向中点
NSLayoutAttributeCenterY,//水平方向中点
//创建redView
UIView *redView = [[UIView alloc]init];
redView.backgroundColor = [UIColor redColor];
redView.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addSubview:redView];
//创建redView第一个约束,相对self.view的左边缘间距20
NSLayoutConstraint * redLeftLc = [NSLayoutConstraint constraintWithItem:redView attribute:NSLayoutAttributeLeftMargin relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeLeft multiplier:1.0f constant:20.0];
//只有在没有参照控件的情况下,约束才加到自身,不然加到父控件上
[self.view addConstraint:redLeftLc];
//创建redView第二个约束,相对self。view的底边缘间距20
NSLayoutConstraint *redBottomLc = [NSLayoutConstraint constraintWithItem:redView attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeBottomMargin multiplier:1.0f constant:-20];//由于是redview相对self.view往上减20,所以是-20
//添加约束
[self.view addConstraint:redBottomLc];
//创建redView第三个约束,设置自身宽,宽可以参照其他控件设置,比如是self.view宽的一半,则应该这样写
/*
[NSLayoutConstraint constraintWithItem:redView attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeWidth multiplier:0.5f constant:0.0];
*/
//这里直接设置自身宽为50
NSLayoutConstraint * redWLc = [NSLayoutConstraint constraintWithItem:redView attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:nil attribute:kNilOptions multiplier:1.0f constant:50.0f];
//由于没有参照物,所以约束添加于自身身上
[redView addConstraint:redWLc];
//创建最后一个约束,自身的高
NSLayoutConstraint * redHLc = [NSLayoutConstraint constraintWithItem:redView attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:kNilOptions multiplier:1.0f constant:50];
//由于没有参照物,所以约束添加于自身身上
[redView addConstraint:redHLc];
//这时请大家想一下,我只需要设置redView与self.view的位置关系,再确定自己的宽高,不就就完成了位置与尺寸这两个必须条件了么?
//先创建一个一个蓝色的view添加到视图上,剩下的就是用autolayout来设置它的“frame”了
UIView *blueView = [[UIView alloc]init];
blueView.backgroundColor = [UIColor blueColor];
blueView.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addSubview:blueView];
self.blueView = blueView;
//创建第一个约束,左边间距,由于是想要与红色有20的间距,那么参照参数“toItem”就应该填redView
NSLayoutConstraint *blueLeft = [NSLayoutConstraint constraintWithItem:blueView attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:redView attribute:NSLayoutAttributeRight multiplier:1.0f constant:20.0f];
//与其他控件发生约束,所以约束添加到父控件上
[self.view addConstraint:blueLeft];
//现在我们已经可以确定自己水平方向的位置了,还差垂直方向的位置,现在我们来创建第二个约束,参照物依然是红色方块,需求是要离self.view底部20间距,这不是正好和红色一样么,那么我们可以直接与红色方块底部对齐就行了
NSLayoutConstraint *blueBottom = [NSLayoutConstraint constraintWithItem:blueView attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:redView attribute:NSLayoutAttributeBottom multiplier:1.0f constant:0.0f];//与红色方块底部对齐,倍数1.0f.差值0.0f
//与其他控件发生约束,所以约束添加到父控件上
[self.view addConstraint:blueBottom];
//剩下两个约束差不多,我就一并描述了,它们都以redView为参照,与其等宽等高
NSLayoutConstraint *blueW = [NSLayoutConstraint constraintWithItem:blueView attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:redView attribute:NSLayoutAttributeWidth multiplier:1.0f constant:0.0f];
[self.view addConstraint:blueW];
NSLayoutConstraint *blueH = [NSLayoutConstraint constraintWithItem:blueView attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:redView attribute:NSLayoutAttributeHeight multiplier:1.0f constant:0.0f];
[self.view addConstraint:blueH];
接下来看看效果图
其实Autolayout的思想非常简单,刚开始使用的时候不要想着马上一气呵成,最好一个控件一个控件的实现依赖,分别满足其位置与尺寸的需求,如果一下子几个控件一起弄的话,你得思路非常清晰,往往大家犯错是犯在约束添多了,而不是添少了
优先级(priority)
//一如往常,先创建黄色View
UIView *yellowV = [[UIView alloc]init];
yellowV.backgroundColor = [UIColor yellowColor];
yellowV.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addSubview:yellowV];
//开始创建约束,第一个约束是什么呢?一看就知道是左间距约束啦
NSLayoutConstraint *yellowLeft = [NSLayoutConstraint constraintWithItem:yellowV attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:blueView attribute:NSLayoutAttributeRight multiplier:1.0f constant:20];
//与其他控件发生约束,所以约束添加到父控件上
[self.view addConstraint:yellowLeft];
//添加底部约束
NSLayoutConstraint *yellowBottom = [NSLayoutConstraint constraintWithItem:yellowV attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeBottom multiplier:1.0f constant:-20];
//与其他控件发生约束,所以约束添加到父控件上
[self.view addConstraint:yellowBottom];
//这里我直接设置宽高约束了,就省事不加参照控件了
NSLayoutConstraint *yellowW = [NSLayoutConstraint constraintWithItem:yellowV attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:nil attribute:kNilOptions multiplier:1.0f constant:50.0f];
[yellowV addConstraint:yellowW];
NSLayoutConstraint *yellowH = [NSLayoutConstraint constraintWithItem:yellowV attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:kNilOptions multiplier:1.0f constant:50.0f];
[yellowV addConstraint:yellowH];
好,现在黄色方块已经添加上去了
接下来我再黄色View添加一个约束,这个约束涉及到优先级
,大家注意看代码了哈
//对黄色View添加约束,约束黄色view与红色View的间距为20
NSLayoutConstraint *yellowAnotherLeft = [NSLayoutConstraint constraintWithItem:yellowV attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:redView attribute:NSLayoutAttributeRight multiplier:1.0f constant:20];
UILayoutPriority priority = 250;//设置优先级
yellowAnotherLeft.priority = priority;
//与其他控件发生约束,所以约束添加到父控件上
[self.view addConstraint:yellowAnotherLeft];
约束冲突
,但是大家注意看这段代码UILayoutPriority priority = 250;//设置优先级
yellowAnotherLeft
这个约束添加了优先级,优先级的范围是0~1000
,数字越大,优先级越高,在不设置的情况下默认为1000-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
//先把蓝色方块从父视图上移除
[self.blueView removeFromSuperview];
//动画更新界面
[UIView animateWithDuration:1.0f animations:^{
[self.view layoutIfNeeded];
}];
}