什么是NSLayoutConstraint?
在xib中,我们可以用拖拽约束的方式来给空间添加约束条件,但是如果控件过多,则整个xib文件中的线条会变得混乱不堪,虽然苹果在极力推荐可视化的加约束方式,但是还是给我们提供了代码的方式来添加约束:NSLayoutConstraint。
如何使用NSLayoutConstraint?
在使用NSLayoutConstraint前,我们需要知道一个小的知识点:Autoresizing Mask。在使用 Auto Layout 时,首先需要将视图的 setTranslatesAutoresizingMaskIntoConstraints属性设置为 NO。这个属性默认为 YES。当它为 YES 时,运行时系统会自动将 Autoresizing Mask 转换为 Auto Layout 的约束,这些约束很有可能会和我们自己添加的产生冲突。 我们常常会忘了做这一步,然后引起的约束报错就是这样的:
在xib中,如果我们勾选了use auto layout,则编译器会自动帮我们关闭Autoresizing Mask,如果是使用代码添加约束,则需要手动关闭Autoresizing Mask。
setTranslatesAutoresizingMaskIntoConstraints这个方法是交给被添加约束的视图来执行的,关闭该视图的Autoresizing Mask。在添加约束前,就应该关闭该属性。
使用NSLayoutConstraint为视图添加约束
Auto Layout 中约束对应的类为 NSLayoutConstraint,一个 NSLayoutConstraint 实例代表一条约束。
使用AutoLayout之前需要知道以下两点:
1.必须设置translatesAutoresizingMaskIntoConstraints为NO
2.如果是viewController则AutoLayout适配写在:
- (void)updateViewConstraints NS_AVAILABLE_IOS(6_0);
如果是view则AutoLayout适配写在:
- (void)updateConstraints NS_AVAILABLE_IOS(6_0) NS_REQUIRES_SUPER;
约束创建方法
NSLayoutConstraint中有两个方法:
- 第一个方法:
+(instancetype)constraintWithItem:(id)view1
attribute:(NSLayoutAttribute)attr1
relatedBy:(NSLayoutRelation)relation
toItem:(nullable id)view2
attribute:(NSLayoutAttribute)attr2
multiplier:(CGFloat)multiplier
constant:(CGFloat)c;
参数说明:
1.第一个参数view1:要设置的视图
2.第二个参数attr1:是个枚举,表示view1要设置的属性
3.第三个参数relation:是个枚举,表示视图view1和view2的指定属性之间的关系
4.第四个参数view2:参照的视图,可以为空
5.第五个参数attr2:是个枚举,表示view2的属性
6.第六个参数multipler:视图view1的指定属性是参照视图view2指定属性的多少倍
7.第七个参数c:视图view1的指定属性需要加的浮点数
根据参数的讲解,得出计算公式如下
view1.attr1 [=,>=,<=] view2.attr2 * multipler + c;
参数详情:
NSLayoutAttribute 是个枚举:
NSLayoutAttributeLeft:视图的左边
NSLayoutAttributeRight:视图的右边
NSLayoutAttributeTop:视图的上边
NSLayoutAttributeBottom:视图的底边
NSLayoutAttributeLeading:在习惯有左向右看的地区,相当于NSLayoutAttributeLeft;在习惯有右向左看的地区,相当于NSLayoutAttributeRight
NSLayoutAttributeTrailing:在习惯有左向右看的地区,相当于NSLayoutAttributeRight;在习惯有右向左看的地区,相当于NSLayoutAttributeLeft
NSLayoutAttributeWidth:视图的宽度
NSLayoutAttributeHeight:视图的高度
NSLayoutAttributeCenterX:视图的中心x轴
NSLayoutAttributeCenterY:视图的中心y轴
NSLayoutAttributeLastBaseline:相当于NSLayoutAttributeBaseline
NSLayoutAttributeBaseline:文本底标线,在大多数视图中等同于NSLayoutAttributeBottom;在少数视图,如UILabel,是指字母的底部出现的位置
NSLayoutAttributeLastFirstline:文本上标线,在大多数视图中等同于NSLayoutAttributeTop;在少数视图,如UILabel,是指字母的上部出现的位置
NSLayoutAttributeNotAnAttribute:没有
NSLayoutRelation 是个枚举:
NSLayoutRelationLessThanOrEqual:表示小于等于<=
NSLayoutRelationEqual:表示等于=
NSLayoutRelationGreaterThanOrEqual:表示大于等于>=
这里有几个注意点:
1.添加约束前确定已经把需要布局的子view添加到父view上了
2.一定要禁止将Autoresizing Mask转换为约束
3.要把子view的约束加在父view上
4.因为iOS中原点在左上角所以使用offset时注意right和bottom用负数
5.如果是设置view自身的属性,不涉及到与其他view的位置约束关系。比如view自身的宽、高等约束时,方法constraintWithItem:的第四个参数view2(secondItem)应设为nil;且第五个参数attire(secondAttribute)应设为NSLayoutAttributeNotAnAttribute 。
6.在设置宽和高这两个约束时,relatedBy参数使用的是 NSLayoutRelationGreaterThanOrEqual,而不是 NSLayoutRelationEqual。因为 Auto Layout 是相对布局,所以通常你不应该直接设置宽度和高度这种固定不变的值,除非你很确定视图的宽度或高度需要保持不变。