在我看來,Autolayout是開發(fā)神器巍佑,但是它也有局限之處斋配。拿cell來舉例孔飒,如果cell中的控件個數(shù)不確定,根據(jù)后臺所給的數(shù)據(jù)來控制顯示控件個數(shù)艰争,那么Autolayout就不能簡單的在xib上“拖”出來坏瞄,而需要在代碼中編寫。這種情況在實際開發(fā)中是很常見的甩卓。我們再來看看原生代碼的手寫約束:
NSLayoutConstraint* leftConstraint = [NSLayoutConstraint constraintWithItem:logoImageView attribute:NSLayoutAttributeLeading relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeLeading multiplier:1.0f constant:0.0f];
//logoImageView右側(cè)與父視圖右側(cè)對齊
NSLayoutConstraint* rightConstraint = [NSLayoutConstraint constraintWithItem:logoImageView attribute:NSLayoutAttributeTrailing relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeTrailing multiplier:1.0f constant:0.0f];
//logoImageView頂部與父視圖頂部對齊
NSLayoutConstraint* topConstraint = [NSLayoutConstraint constraintWithItem:logoImageView attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeTop multiplier:1.0f constant:0.0f];
//logoImageView高度為父視圖高度一半
NSLayoutConstraint* heightConstraint = [NSLayoutConstraint constraintWithItem:logoImageView attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeHeight multiplier:0.5f constant:0.0f];
//iOS 6.0或者7.0調(diào)用addConstraints
//[self.view addConstraints:@[leftConstraint, rightConstraint, topConstraint, heightConstraint]];
是不是很難記鸠匀?和frame相比,也變得更抽象逾柿,代碼量也更多缀棍。誰會愿意擺放一個控件寫那么多代碼宅此?幸運的是,現(xiàn)在我們有很多第三方框架來幫我們簡化這些代碼爬范。
Masonry和SDAutolayout
目前網(wǎng)上流行AutoLayout框架主要是Masonry和SDAutolayout父腕。前者是我目前項目中常用的框架,主要是用block回調(diào)青瀑,并且將復(fù)雜的約束講話成MASConstraintMaker進行約束封裝璧亮。后者是聲稱比Masonry更簡單易用的約束框架,采用鏈式編程的思想對約束進行封裝,并能實現(xiàn)cell高度自適應(yīng)狱窘。下面我們來看看具體的使用方法杜顺。
Masonry框架
- Masonry是公認非常簡潔優(yōu)美的一款A(yù)utolayout框架
- gitHub地址:https://github.com/SnapKit/Masonry
- 推薦用cocoapods安裝(如果不知道還是網(wǎng)上搜索下,開發(fā)必備)pod search Masonry
- 非常適合拿來練手
首先#import "Masonry.h"
導入頭文件蘸炸,然后就可以用代碼進行約束編寫:
//初始化一個view
UIView * redView = [[UIView alloc]init];
redView.backgroundColor = [UIColor redColor];
//然后將這個view添加到界面上
[self.view addSubview:redView];
//然后進行約束設(shè)置
[redView mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(self.view).offset(100);
make.right.equalTo(self.view).offset(-200);
make.top.equalTo(self.view).offset(100);
make.height.mas_equalTo(100);
}];
先看這一段代碼躬络,首先創(chuàng)建了一個UIView,將背景色設(shè)成紅色,然后進行約束設(shè)置搭儒。Masonry的命名都很直觀穷当,唯一要解釋的可能就是這個make。我們可以理解成這個make就是redView本身淹禾,make.left.equalTo(self.view).offset(100);
就是設(shè)置redView
的左側(cè)相對于self.view
偏移量為100馁菜。這種思想和在xib上拖線的思想是一致的。再來看看設(shè)置自己本身高度的約束make.height.mas_equalTo(100);
和上面一條唯一的區(qū)別就是mas_equalTo
铃岔。還有一點需要注意的是.offset
的值汪疮,如果前面是make.left(或者make.leading)和make.top,那么offset中設(shè)置的值為正數(shù),如果是make.right(或者make.trailing)和make.bottom,那么offset中的值設(shè)成負數(shù)毁习。
我們都知道智嚷,約束都有優(yōu)先級。在Masonry語法中設(shè)置優(yōu)先級也很簡單纺且,make.height.mas_equalTo(100).priority(500);
只要在后面添上.priority(優(yōu)先級)就行了盏道,如果不添加,默認優(yōu)先級為1000载碌。
再看另外一個例子:
//初始化一個view
UIView * redView = [[UIView alloc]init];
redView.backgroundColor = [UIColor redColor];
UIView * greenView = [[UIView alloc]init];
greenView.backgroundColor = [UIColor greenColor];
//然后將這個view添加到界面上
[self.view addSubview:redView];
[self.view addSubview:greenView];
//然后進行約束設(shè)置
[redView mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(self.view).offset(100);
make.right.equalTo(greenView.mas_left).offset(-50);
make.top.equalTo(self.view).offset(100);
make.height.mas_equalTo(100).priority(500);
}];
[greenView mas_makeConstraints:^(MASConstraintMaker *make) {
make.right.equalTo(self.view).offset(-30);
make.top.equalTo(self.view).offset(100);
make.height.mas_equalTo(100);
make.width.mas_equalTo(100);
}];
這里要注意的是make.right.equalTo(greenView.mas_left).offset(-50);
這個寫法猜嘱,中間的括號是greenView.mas_left,應(yīng)該也很好理解嫁艇。
效果:
關(guān)于mas_makeConstraints
朗伶,mas_updateConstraints
和mas_remakeConstraints
的用法都是相同的,官方的API文檔是這樣描述的:
/**
* Creates a MASConstraintMaker with the callee view.
* Any constraints defined are added to the view or the appropriate superview once the block has finished executing
*
* @param block scope within which you can build up the constraints which you wish to apply to the view.
*
* @return Array of created MASConstraints
*/
- (NSArray *)mas_makeConstraints:(void(^)(MASConstraintMaker *make))block;
/**
* Creates a MASConstraintMaker with the callee view.
* Any constraints defined are added to the view or the appropriate superview once the block has finished executing.
* If an existing constraint exists then it will be updated instead.
*
* @param block scope within which you can build up the constraints which you wish to apply to the view.
*
* @return Array of created/updated MASConstraints
*/
- (NSArray *)mas_updateConstraints:(void(^)(MASConstraintMaker *make))block;
/**
* Creates a MASConstraintMaker with the callee view.
* Any constraints defined are added to the view or the appropriate superview once the block has finished executing.
* All constraints previously installed for the view will be removed.
*
* @param block scope within which you can build up the constraints which you wish to apply to the view.
*
* @return Array of created/updated MASConstraints
*/
- (NSArray *)mas_remakeConstraints:(void(^)(MASConstraintMaker *make))block;
總的來說步咪,mas_makeConstraints
就是在原基礎(chǔ)上添加約束腕让,mas_updateConstraints
就是更新約束,mas_remakeConstraints
就是先去除原有約束再添加約束
總結(jié)
- 先把要添加約束的控件add到父視圖上(addSubview)
- 使用mas_makeConstraints添加約束,make可以設(shè)想成這個控件本身
- 如果是添加左側(cè)或者上側(cè)的約束纯丸,offset用正數(shù),如果添加右側(cè)和下側(cè)的約束静袖,offset用負數(shù)
- 設(shè)置本身的約束(height觉鼻、width)用mas_equalTo
- 如果兩個平級控件之間設(shè)置約束,第二個控件要帶上(mas_方向)
我是翻滾的牛寶寶队橙,歡迎大家評論交流~