Autolayout是iOS6以后才出現(xiàn)的新技術(shù),比f(wàn)rame使用更加地方便,比Autoresizing更加地強(qiáng)大。下面,就介紹一下在項(xiàng)目開(kāi)發(fā)中使用Autolayout幾種途徑。
純代碼實(shí)現(xiàn)Autolayout
1.NSLayoutConstraint
[NSLayoutConstraint constraintWithItem:(id)item attribute:(NSLayoutAttribute)attribute relatedBy:(NSLayoutRelation)relation toItem:(id)otherItem attribute:(NSLayoutAttribute)otherAttribute multiplier:(CGFloat)multiplier constant:(CGFloat)constant]
舉個(gè)簡(jiǎn)單的例子,我們?cè)谒赾ontroller默認(rèn)view上添加一個(gè)子視圖subview,subview的寬高為view寬高的1/3,距離view左邊100,距離view上邊150,就可以用下面代碼這樣實(shí)現(xiàn):
UIView *subView = [[UIView alloc]init];
subView.backgroundColor = [UIColor greenColor];
[self.view addSubview:subView];
subView.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:subView attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeTop multiplier:1. constant:150]];
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:subView attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeHeight multiplier:0.3 constant:0]];
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:subView attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeWidth multiplier:0.3 constant:0]];
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:subView attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeLeft multiplier:1. constant:100]];
運(yùn)行結(jié)果:

上面方法參數(shù)說(shuō)明:
第一個(gè)參數(shù):指定約束左邊的視圖view1
第二個(gè)參數(shù):指定view1的屬性attr1
第三個(gè)參數(shù):指定左右兩邊的視圖的關(guān)系relation
第四個(gè)參數(shù):指定約束右邊的視圖view2
第五個(gè)參數(shù):指定view2的屬性attr2
第六個(gè)參數(shù):指定一個(gè)與view2屬性相乘的乘數(shù)multiplier
第七個(gè)參數(shù):指定一個(gè)與view2屬性相加的浮點(diǎn)數(shù)constant
依據(jù)的公式是:view1.attr1 = view2.attr2*multiplier +constant
NSLayoutAttribute的類型:
NSLayoutAttributeLeft 視圖的左邊
NSLayoutAttributeRight 視圖的右邊
NSLayoutAttributeTop 視圖的上邊
NSLayoutAttributeBottom 視圖的下邊
NSLayoutAttributeLeading 視圖的前邊
NSLayoutAttributeTrailing 視圖的后邊
NSLayoutAttributeWidth 視圖的寬度
NSLayoutAttributeHeight 視圖的高度
NSLayoutAttributeCenterX 視圖的中點(diǎn)的X值
NSLayoutAttributeCenterY 視圖中點(diǎn)的Y值
NSLayoutAttributeBaseline 視圖的基準(zhǔn)線
NSLayoutAttributeNotAnAttribute 無(wú)屬性
NSLayoutRelation的類型:
NSLayoutRelationLessThanOrEqual 關(guān)系小于或等于
NSLayoutRelationEqual 視圖關(guān)系等于
NSLayoutRelationGreaterThanOrEqual 視圖關(guān)系大于或等于
這里要說(shuō)明一下,設(shè)置約束之前必須要求確保子視圖添加到了父視圖上了(如:[self.view addSubview:subView]),并且被約束的視圖的translatesAutoresizingMaskIntoConstraints = NO,不然就會(huì)發(fā)生程序crash。
1.1 VFL(Visual format language)
VFL是NSLayoutConstraint使用特定的NSString類型字符串來(lái)創(chuàng)建Constraint,通過(guò)下面方法就可以創(chuàng)建
[NSLayoutConstraint
constraintsWithVisualFormat:(NSString *)format options:(NSLayoutFormatOptions)opts metrics:(nullable NSDictionary<NSString *,id> *)metrics views:(NSDictionary<NSString *, id> *)views]
關(guān)于VFL格式使用規(guī)則,可以參考這篇博客http://blog.csdn.net/mmoaay/article/details/46707103
2.Masonry
通過(guò)上面的NSLayoutConstraint使用可以發(fā)現(xiàn),每次添加一條約束就要寫(xiě)一長(zhǎng)串的代碼,如果視圖約束很多的話,那么就要寫(xiě)很多的代碼,所以就有人基于NSLayoutConstraints進(jìn)行了封裝。Masonry就是基于NSLayoutConstraints封裝的輕量級(jí)的第三方開(kāi)源框架之一。所以實(shí)例1.png可以通過(guò)Masonry實(shí)現(xiàn):
UIView *subView = [[UIView alloc]init];
subView.backgroundColor = [UIColor greenColor];
[self.view addSubview:subView];
__weak typeof(self) weakSelf = self;
[subView mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.mas_equalTo(@100);
make.top.mas_equalTo(@150);
make.width.mas_equalTo(weakSelf.view.mas_width).multipliedBy(0.3);
make.height.mas_equalTo(weakSelf.view.mas_height).multipliedBy(0.3);
}];
xib 中Autolayout設(shè)置
在xib中使用Autolayout,是一種非常直觀,非常方便的一種方式。我們可以在不用代碼就可以實(shí)現(xiàn)各種布局。

按照?qǐng)D中所示,可以很快的設(shè)置子視圖Top,Leading,Bottom,Trailing的約束,切換到導(dǎo)航欄Show the size inspect按鈕可以看到已經(jīng)設(shè)置好的各個(gè)約束,并且可以對(duì)設(shè)置好約束進(jìn)行修改,如修改每個(gè)約束中constant,priority,multiplier值等。
當(dāng)然,不管是純代碼還是xib實(shí)現(xiàn)Autolayout,都可能遇到約束沖突的情況。比如,一個(gè)subview子視圖基于父視圖設(shè)置了Top,Leading,Bottom,Trailing四個(gè)約束,并且又設(shè)置了subview的高度height,這樣運(yùn)行就是出現(xiàn)Probably at least one of the constraints in the following list is one you don't want. 的警告,因?yàn)閟ubview子視圖高度height約束和Top或Bottom產(chǎn)生了沖突。
約束沖突可以通過(guò)修改Autolayout約束的優(yōu)先級(jí)不同的方式進(jìn)行解決,在Autolayout中每個(gè)約束都有一個(gè)優(yōu)先級(jí)priority,priority的范圍是1 ~ 1000,默認(rèn)創(chuàng)建的約束priority最高是1000,并且系統(tǒng)默認(rèn)提供了Required(1000)、High(750)、Low(250)三種priority。所以對(duì)于上述subview子視圖產(chǎn)生的約束沖突問(wèn)題,可以通過(guò)修改subview 子視圖Top或Bottom約束的priority小于1000就可以解決沖突問(wèn)題。
小結(jié)
以上介紹了Autolayout幾種使用的途徑。其實(shí),每種途徑都有很多的內(nèi)容,這里對(duì)每種途徑只是簡(jiǎn)單的說(shuō)明了一下,具體使用Autolayout哪種途徑,還需要根據(jù)自己的項(xiàng)目情況及自己掌握程度而定。