Autolayout進階之代碼編寫約束(一)

在我看來,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_updateConstraintsmas_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_方向)

我是翻滾的牛寶寶队橙,歡迎大家評論交流~

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末坠陈,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子捐康,更是在濱河造成了極大的恐慌仇矾,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,372評論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件解总,死亡現(xiàn)場離奇詭異贮匕,居然都是意外死亡,警方通過查閱死者的電腦和手機花枫,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評論 3 392
  • 文/潘曉璐 我一進店門刻盐,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人劳翰,你說我怎么就攤上這事敦锌。” “怎么了佳簸?”我有些...
    開封第一講書人閱讀 162,415評論 0 353
  • 文/不壞的土叔 我叫張陵乙墙,是天一觀的道長。 經(jīng)常有香客問我生均,道長听想,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,157評論 1 292
  • 正文 為了忘掉前任疯特,我火速辦了婚禮哗魂,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘漓雅。我一直安慰自己录别,他們只是感情好,可當我...
    茶點故事閱讀 67,171評論 6 388
  • 文/花漫 我一把揭開白布邻吞。 她就那樣靜靜地躺著组题,像睡著了一般。 火紅的嫁衣襯著肌膚如雪抱冷。 梳的紋絲不亂的頭發(fā)上崔列,一...
    開封第一講書人閱讀 51,125評論 1 297
  • 那天,我揣著相機與錄音,去河邊找鬼赵讯。 笑死盈咳,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的边翼。 我是一名探鬼主播鱼响,決...
    沈念sama閱讀 40,028評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼组底!你這毒婦竟也來了丈积?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,887評論 0 274
  • 序言:老撾萬榮一對情侶失蹤债鸡,失蹤者是張志新(化名)和其女友劉穎江滨,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體厌均,經(jīng)...
    沈念sama閱讀 45,310評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡唬滑,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,533評論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了莫秆。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片间雀。...
    茶點故事閱讀 39,690評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖镊屎,靈堂內(nèi)的尸體忽然破棺而出惹挟,到底是詐尸還是另有隱情,我是刑警寧澤缝驳,帶...
    沈念sama閱讀 35,411評論 5 343
  • 正文 年R本政府宣布连锯,位于F島的核電站,受9級特大地震影響用狱,放射性物質(zhì)發(fā)生泄漏运怖。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,004評論 3 325
  • 文/蒙蒙 一夏伊、第九天 我趴在偏房一處隱蔽的房頂上張望摇展。 院中可真熱鬧,春花似錦溺忧、人聲如沸咏连。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽祟滴。三九已至,卻和暖如春歌溉,著一層夾襖步出監(jiān)牢的瞬間垄懂,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,812評論 1 268
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留草慧,地道東北人桶蛔。 一個月前我還...
    沈念sama閱讀 47,693評論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像冠蒋,于是被迫代替她去往敵國和親羽圃。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,577評論 2 353

推薦閱讀更多精彩內(nèi)容