什么是NSLayoutConstraint?
在xib中,我們可以用拖拽約束的方式來給空間添加約束條件,但是如果控件過多,則整個(gè)xib文件中的線條會變得混亂不堪,雖然蘋果在極力推薦可視化的加約束方式,但是還是給我們提供了代碼的方式來添加約束:NSLayoutConstraint。
如何使用NSLayoutConstraint?
在使用NSLayoutConstraint前,我們需要知道一個(gè)小的知識點(diǎn):Autoresizing Mask。在使用 Auto Layout 時(shí),首先需要將視圖的 setTranslatesAutoresizingMaskIntoConstraints屬性設(shè)置為 NO。這個(gè)屬性默認(rèn)為 YES。當(dāng)它為 YES 時(shí),運(yùn)行時(shí)系統(tǒng)會自動(dòng)將 Autoresizing Mask 轉(zhuǎn)換為 Auto Layout 的約束,這些約束很有可能會和我們自己添加的產(chǎn)生沖突。 我們常常會忘了做這一步,然后引起的約束報(bào)錯(cuò)就是這樣的:

在xib中,如果我們勾選了use auto layout,則編譯器會自動(dòng)幫我們關(guān)閉Autoresizing Mask,如果是使用代碼添加約束,則需要手動(dòng)關(guān)閉Autoresizing Mask。
setTranslatesAutoresizingMaskIntoConstraints這個(gè)方法是交給被添加約束的視圖來執(zhí)行的,關(guān)閉該視圖的Autoresizing Mask。在添加約束前,就應(yīng)該關(guān)閉該屬性。
使用NSLayoutConstraint為視圖添加約束
Auto Layout 中約束對應(yīng)的類為 NSLayoutConstraint,一個(gè) NSLayoutConstraint 實(shí)例代表一條約束。
使用AutoLayout之前需要知道以下兩點(diǎn):
1.必須設(shè)置translatesAutoresizingMaskIntoConstraints為NO
2.如果是viewController則AutoLayout適配寫在:
- (void)updateViewConstraints NS_AVAILABLE_IOS(6_0);
如果是view則AutoLayout適配寫在:
- (void)updateConstraints NS_AVAILABLE_IOS(6_0) NS_REQUIRES_SUPER;
約束創(chuàng)建方法
NSLayoutConstraint中有兩個(gè)方法:
- 第一個(gè)方法:
+(instancetype)constraintWithItem:(id)view1
attribute:(NSLayoutAttribute)attr1
relatedBy:(NSLayoutRelation)relation
toItem:(nullable id)view2
attribute:(NSLayoutAttribute)attr2
multiplier:(CGFloat)multiplier
constant:(CGFloat)c;
參數(shù)說明:
1.第一個(gè)參數(shù)view1:要設(shè)置的視圖
2.第二個(gè)參數(shù)attr1:是個(gè)枚舉,表示view1要設(shè)置的屬性
3.第三個(gè)參數(shù)relation:是個(gè)枚舉,表示視圖view1和view2的指定屬性之間的關(guān)系
4.第四個(gè)參數(shù)view2:參照的視圖,可以為空
5.第五個(gè)參數(shù)attr2:是個(gè)枚舉,表示view2的屬性
6.第六個(gè)參數(shù)multipler:視圖view1的指定屬性是參照視圖view2指定屬性的多少倍
7.第七個(gè)參數(shù)c:視圖view1的指定屬性需要加的浮點(diǎn)數(shù)
根據(jù)參數(shù)的講解,得出計(jì)算公式如下
view1.attr1 [=,>=,<=] view2.attr2 * multipler + c;
參數(shù)詳情:
NSLayoutAttribute 是個(gè)枚舉:
NSLayoutAttributeLeft:視圖的左邊
NSLayoutAttributeRight:視圖的右邊
NSLayoutAttributeTop:視圖的上邊
NSLayoutAttributeBottom:視圖的底邊
NSLayoutAttributeLeading:在習(xí)慣有左向右看的地區(qū),相當(dāng)于NSLayoutAttributeLeft;在習(xí)慣有右向左看的地區(qū),相當(dāng)于NSLayoutAttributeRight
NSLayoutAttributeTrailing:在習(xí)慣有左向右看的地區(qū),相當(dāng)于NSLayoutAttributeRight;在習(xí)慣有右向左看的地區(qū),相當(dāng)于NSLayoutAttributeLeft
NSLayoutAttributeWidth:視圖的寬度
NSLayoutAttributeHeight:視圖的高度
NSLayoutAttributeCenterX:視圖的中心x軸
NSLayoutAttributeCenterY:視圖的中心y軸
NSLayoutAttributeLastBaseline:相當(dāng)于NSLayoutAttributeBaseline
NSLayoutAttributeBaseline:文本底標(biāo)線,在大多數(shù)視圖中等同于NSLayoutAttributeBottom;在少數(shù)視圖,如UILabel,是指字母的底部出現(xiàn)的位置
NSLayoutAttributeLastFirstline:文本上標(biāo)線,在大多數(shù)視圖中等同于NSLayoutAttributeTop;在少數(shù)視圖,如UILabel,是指字母的上部出現(xiàn)的位置
NSLayoutAttributeNotAnAttribute:沒有
NSLayoutRelation 是個(gè)枚舉:
NSLayoutRelationLessThanOrEqual:表示小于等于<=
NSLayoutRelationEqual:表示等于=
NSLayoutRelationGreaterThanOrEqual:表示大于等于>=
這里有幾個(gè)注意點(diǎn):
1.添加約束前確定已經(jīng)把需要布局的子view添加到父view上了
2.一定要禁止將Autoresizing Mask轉(zhuǎn)換為約束
3.要把子view的約束加在父view上
4.因?yàn)閕OS中原點(diǎn)在左上角所以使用offset時(shí)注意right和bottom用負(fù)數(shù)
5.如果是設(shè)置view自身的屬性,不涉及到與其他view的位置約束關(guān)系。比如view自身的寬、高等約束時(shí),方法constraintWithItem:的第四個(gè)參數(shù)view2(secondItem)應(yīng)設(shè)為nil;且第五個(gè)參數(shù)attire(secondAttribute)應(yīng)設(shè)為NSLayoutAttributeNotAnAttribute 。
6.在設(shè)置寬和高這兩個(gè)約束時(shí),relatedBy參數(shù)使用的是 NSLayoutRelationGreaterThanOrEqual,而不是 NSLayoutRelationEqual。因?yàn)?Auto Layout 是相對布局,所以通常你不應(yīng)該直接設(shè)置寬度和高度這種固定不變的值,除非你很確定視圖的寬度或高度需要保持不變。