可能有些人看到NSLayoutConstraint有點(diǎn)陌生,因?yàn)樗⒉皇荛_(kāi)發(fā)人員的歡迎,不怎么好用但是還有有了解的必要的;其實(shí)它是實(shí)現(xiàn)自動(dòng)布局方式之一,因?yàn)槲覀兠總€(gè)APP都需要去適配,有人使用第三方Masonry,有人在Xib或者storyBoard中使用AutoLayout或者是Size Class進(jìn)行布局;今天我們就認(rèn)識(shí)一下NSLayoutConstraint,順便給大家介紹好用的工具!

需要把控件的屬性設(shè)置為 setTranslatesAutoresizingMaskIntoConstraints:NO,為了不讓Contraint和view本身的autoresize屬性發(fā)生沖突;如果你沒(méi)有設(shè)置該屬性,你的布局不起作用或者會(huì)報(bào)錯(cuò)。
主要的兩個(gè)方法:
/*
format:V:|-(>=XXX) :表示垂直方向上相對(duì)于SuperView大于、等于、小于某個(gè)距離 若是要定義水平方向,則將V:改成H:即可 在接著后面-[]中括號(hào)里面對(duì)當(dāng)前的View/控件 的高度/寬度進(jìn)行設(shè)定;
opts:options:字典類型的值;這里的值一般在系統(tǒng)定義的一個(gè)enum里面選取
metrics:metrics:nil;一般為nil ,參數(shù)類型為NSDictionary,從外部傳入 //衡量標(biāo)準(zhǔn)
views:views:就是上面所加入到NSDictionary中的綁定的View
### 使用規(guī)則:
|: 表示父視圖
-:表示距離
V: :表示垂直
H: :表示水平
>= :表示視圖間距、寬度和高度必須大于或等于某個(gè)值
<= :表示視圖間距、寬度和高度必須小宇或等于某個(gè)值
== :表示視圖間距、寬度或者高度必須等于某個(gè)值
@ :>=、<=、== 限制 最大為 1000
*/
+ (NSArray<__kindof NSLayoutConstraint *> *)constraintsWithVisualFormat:(NSString *)format options:(NSLayoutFormatOptions)opts metrics:(nullable NSDictionary<NSString *,id> *)metrics views:(NSDictionary<NSString *, id> *)views;
/*
view1:指定約束左邊的視圖view1
attr1:指定view1的屬性attr1,具體屬性見(jiàn)文末。
relation:指定左右兩邊的視圖的關(guān)系relation,具體關(guān)系見(jiàn)文末。
view2:指定約束右邊的視圖view2
attr2:指定view2的屬性attr2,具體屬性見(jiàn)文末。
multiplier:指定一個(gè)與view2屬性相乘的乘數(shù)multiplier
c:指定一個(gè)與view2屬性相加的浮點(diǎn)數(shù)constant
這個(gè)函數(shù)的對(duì)照公式為: view1.attr1 <relation> view2.attr2 * multiplier + constant
*/
/*
NSLayoutAttribute:
NSLayoutAttributeLeft = 1, // 左側(cè)
NSLayoutAttributeRight, // 右側(cè)
NSLayoutAttributeTop, // 頂部
NSLayoutAttributeBottom, // 底部
NSLayoutAttributeLeading, // 首部
NSLayoutAttributeTrailing, // 尾部
NSLayoutAttributeWidth, // 寬度
NSLayoutAttributeHeight, // 高度
NSLayoutAttributeCenterX, // X軸中心
NSLayoutAttributeCenterY, //
NSLayoutAttributeBaseline,
NSLayoutAttributeNotAnAttribute = 0
*/
+(instancetype)constraintWithItem:(id)view1 attribute:(NSLayoutAttribute)attr1 relatedBy:(NSLayoutRelation)relation toItem:(nullable id)view2 attribute:(NSLayoutAttribute)attr2 multiplier:(CGFloat)multiplier constant:(CGFloat)c;
實(shí)際應(yīng)用(使用工具就可以生成):
// align imageview from the left and right
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-0-[imageview]-0-|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(imageview)]];
// align imageview from the top and bottom
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-0-[imageview]-0-|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(imageview)]];
// center imageview horizontally in self.view
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:imageview attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeCenterX multiplier:1.0 constant:0.0]];
// center imageview vertically in self.view
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:imageview attribute:NSLayoutAttributeCenterY relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeCenterY multiplier:1.0 constant:0.0]];
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:imageview attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationLessThanOrEqual toItem:self.view attribute:NSLayoutAttributeWidth multiplier:0.5 constant:0.0]];
Auto Layout 更新約束的幾個(gè)方法
- setNeedsLayout:告知頁(yè)面需要更新,但是不會(huì)立刻開(kāi)始更新。執(zhí)行后會(huì)立刻調(diào)用layoutSubviews。
- layoutIfNeeded:告知頁(yè)面布局立刻更新。所以一般都會(huì)和setNeedsLayout一起使用。如果希望立刻生成新的frame需要調(diào)用此方法,利用這點(diǎn)一般布局動(dòng)畫(huà)可以在更新布局后直接使用這個(gè)方法讓動(dòng)畫(huà)生效。
- layoutSubviews:系統(tǒng)重寫(xiě)布局。
- setNeedsUpdateConstraints:告知需要更新約束,但是不會(huì)立刻開(kāi)始。
- updateConstraintsIfNeeded:告知立刻更新約束。
- updateConstraints:系統(tǒng)更新約束。