Masonry 自動布局 及注意點

TIPS: 如有錯誤之處歡迎批評指正

使用Masonry,通過代碼來進(jìn)行布局

  • equalto 和 mas_equalto 是有區(qū)別的窖式。但是我們不打算去了解蚁飒,可以通過添加以下代碼來統(tǒng)一。
    • 注意B艽拆吆! 宏定義必須要放在 import 引入頭文件之前实抡!
//define this constant if you want to use Masonry without the 'mas_' prefix
#define MAS_SHORTHAND
//define this constant if you want to enable auto-boxing for default syntax
#define MAS_SHORTHAND_GLOBALS

#import "Masonry.h"
  • 使用masonry的步驟及注意點熏版。先來看下面這段代碼

    • 進(jìn)行約束的 self.SelChildView必須已經(jīng)被addView添加過咖驮。也就是說必須已經(jīng)有父類了,否則報錯
    • make.top .bottom .left .right .等等方向equalTo后面()的內(nèi)容

    必須是一個CGFloat启妹,如果是和某個view有關(guān)系筛严,調(diào)用的時候不能直接用mv.openDrawerButton.bottom,必須用mv.openDrawerButton.mas_bottom
    • make.size .width .height等等尺寸equalTo后面()的內(nèi)容
      必須是一個具體的CGFloat數(shù),不能用 mas_width 等等饶米,否則會 上面的IBAction不響應(yīng)
    • 如果出現(xiàn)IBAction無響應(yīng)脑漫,多半是make.size/width/height的約束沒做好
    • with和and都是一個宏,可以查看他咙崎,其實就是一個return self
    self.SelChildView = [[UISegmentedControl alloc] initWithItems:@[@"藍(lán)牙連接",@"WiFi連接"]];
    [self.view addSubview:self.SelChildView];
    // add constrains
    [self.SelChildView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.height.equalTo(48.0f);
        make.top.equalTo(mv.openDrawerButton.mas_bottom).with.offset(8.0f);
        make.centerX.equalTo(mv.view。mas_centerX);
        make.left.equalTo(mv.view).with.offset(8.0f);
        make.right.equalTo(mv.view).with.offset(-8.0f);
        make.width.equalTo(self.SelChildView.frame.size.width);//直接用equalTo(self.SelChildView.mas_width)可能會導(dǎo)致SelChildView上面的控件失效
        make.height.equalTo(self.SelChildView.frame.size.height);//直接用equalTo(self.SelChildView.mas_height)可能會導(dǎo)致SelChildView上面的控件失效
    }];
  • 使用masonry進(jìn)行約束創(chuàng)建的尺寸吨拍,并不等于你已經(jīng)創(chuàng)建了他的frame褪猛!
    • 我們來解釋下下面這張圖。


    • 如果我們不寫 frame的那句羹饰,而用make.size.equalTo(CGSizeMake(5,5)); 我們看到的效果是一樣的伊滋。

但是!如果這樣做了队秩,是無法獲取到他的frame的值的笑旺。通過打印他的x,y,width,height會發(fā)現(xiàn)是0

  • 使用masonry的實質(zhì)還是調(diào)用了ios7以后的autolayout,如果要升級frame馍资,必須在最后增加一句
[self.currentView.superview layoutIfNeeded];//打印他的frame發(fā)現(xiàn)已經(jīng)更新

使用和不使用Masonry下的尺寸問題

  • 比如說筒主,[[UIView alloc] initWithFrame],這個frame的大小是 5x5的大小。
    然后我insert一個image,大小是30x30鸟蟹,最后顯示的時候乌妙,我們看到的圖片是30x30的
  • 縮放比例,只能通過改變他的長寬來實現(xiàn)建钥,不能用 multipliedBy 來實現(xiàn)等比例縮放藤韵,不知道是什么原因!熊经! 坑掉過一次就不要忘記T笏摇欲险!
  • 等比例縮放的實例:
    [self.openDrawerButton mas_makeConstraints:^(MASConstraintMaker *make) {
        make.top.equalTo(self.view).with.offset(20.0f);
        make.left.equalTo(self.view).with.offset(11.0f);
        // 等比例縮小 0.8
        CGSize size = CGSizeMake(0.8*self.openDrawerButton.frame.size.width, 0.8*self.openDrawerButton.frame.size.height);
        make.size.mas_equalTo(size);//如果添加了宏定義,這里可以不用mas_
    }];

Masonry 實例匹涮,分別約束代碼創(chuàng)建和 XIB / Storyboard 創(chuàng)建的UIView

Demo 中討論了masonry配合實現(xiàn)動畫時候碰見的四種情形天试,分別是:

trytry.gif
序號 Masonry 純Frame XIB 純代碼 可行動畫 備注
1 ? ?? ? ?? 卷軸/平移 不使用masonry,通過純代碼和frame 創(chuàng)建卷軸動畫/平移動畫
2 ?? ? ? ?? 卷軸/平移 嘗試通過masonry+純代碼方式創(chuàng)建卷軸動畫/平移,用masonry來升級 frame
3 ? ?? ?? ? 平移/橫向縮放 通過XIB創(chuàng)建DIYView + frame創(chuàng)建平移動畫,證明無法使用卷軸動畫焕盟。因為尺寸不可變(width可變秋秤,height不行)
4 ?? ? ?? ? 平移/橫向縮放 通過XIB創(chuàng)建DIYView + masonry 創(chuàng)建平移動畫和卷軸動畫(width可變,height不行),用masonry來升級 frame

下面是四個情形的代碼

TIPS: 說明下使用masonry升級frame脚翘,形成動畫的注意點:

  • mas_makeConstrains之后灼卢,在后面要加上 [self.viewX.superview layoutIfNeeded]; 升級frame
  • 動畫中調(diào)用mas_updateConstrains升級他的約束,然后也要調(diào)用一次[self.viewX.superview layoutIfNeeded]; 升級frame
  • 如果約束的是XIB的DIYView来农,masonry的約束可能和XIB中的約束沖突鞋真,如果使用縮放,注意make.size的值要設(shè)置好沃于,否則可能IBAction失效
    // Step 1, 通過純代碼和frame 創(chuàng)建卷軸動畫/平移動畫
    self.View1 = [[UIView alloc] initWithFrame:CGRectMake(0,200, [UIScreen mainScreen].bounds.size.width, 0)];
    self.View1.backgroundColor = [UIColor greenColor];
    UILabel* lb = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 50, 50)];
    lb.text = @"TTY";
    [self.view addSubview:self.View1];
    // 動畫
    [UIView animateWithDuration:10.0
                          delay:0
                        options:UIViewAnimationOptionBeginFromCurrentState
                     animations:^{
                         self.View1.frame = CGRectMake(0, 200, [UIScreen mainScreen].bounds.size.width, 80);
                         dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
                             [self.View1 addSubview:lb];
                         });
                     }
                     completion:^(BOOL finished) {
                     }];
    // Step 2涩咖, 嘗試通過masonry+純代碼方式創(chuàng)建卷軸動畫,用masonry來升級 frame
    self.View2 = [[UIView alloc] init];
    self.View2.backgroundColor = [UIColor blackColor];
    [self.view addSubview:self.View2];
    
    [self.View2 mas_makeConstraints:^(MASConstraintMaker *make) {
        make.top.mas_equalTo(300);
        make.left.mas_equalTo(100);
        make.size.mas_equalTo(CGSizeMake(100, 100));
    }];
    NSLog(@"masonry 之前size = %f,%f",self.View2.frame.size.width,self.View2.frame.size.height);
    [self.View2.superview layoutIfNeeded];
    
    [UIView animateWithDuration:10.0
                     animations:^{
                         [self.View2 mas_updateConstraints:^(MASConstraintMaker *make) {
                             make.left.mas_equalTo(200);
                         }];
                         [self.View2.superview layoutIfNeeded];
                     }];
    NSLog(@"masonry 之后size = %f,%f",self.View2.frame.size.width,self.View2.frame.size.height);
// step 3 通過XIB創(chuàng)建DIYView + frame創(chuàng)建滾動動畫,證明無法使用卷軸動畫繁莹。因為尺寸不可變(寬度可以用屏幕寬度賦值檩互,除此其他不行),只能使用滾動動畫
    self.View3 = [[NSBundle mainBundle] loadNibNamed:@"BossView"
                                               owner:self
                                             options:nil].lastObject;
    CGRect view3rect = CGRectMake([UIScreen mainScreen].bounds.size.width, 400, [UIScreen mainScreen].bounds.size.width, self.View3.frame.size.height);
    self.View3.frame = view3rect;
    [self.view addSubview:self.View3];
    [UIView animateWithDuration:5.0
                          delay:0
                        options:UIViewAnimationOptionBeginFromCurrentState
                     animations:^{
                         CGRect view3rect = CGRectMake(0, 400, [UIScreen mainScreen].bounds.size.width, self.View3.frame.size.height);
                         self.View3.frame = view3rect;
                     } completion:^(BOOL finished) {
                     }];

    // step 4 通過XIB創(chuàng)建DIYView + masonry 創(chuàng)建滾動動畫和卷軸動畫(寬度可以改咨演,長度不能改)
    self.View4 = [[NSBundle mainBundle] loadNibNamed:@"BossView"
                                               owner:self
                                             options:nil].lastObject;
    
    [self.view addSubview:self.View4];
    [self.View4 mas_makeConstraints:^(MASConstraintMaker *make) {
        CGSize realsize = CGSizeMake(self.View4.bounds.size.width,0 );
        make.size.equalTo(realsize);
        make.top.equalTo(self.view.mas_top).with.offset(600);
        make.centerX.equalTo(self.view.mas_centerX);
    }];
    [self.View4.superview layoutIfNeeded];
    NSLog(@"View4 masonry 之后size = %f,%f",self.View4.frame.size.width,self.View4.frame.size.height);
    [UIView animateWithDuration:10
                     animations:^{
                         [self.View4 mas_updateConstraints:^(MASConstraintMaker *make) {
                             CGSize realsize = CGSizeMake([UIScreen mainScreen].bounds.size.width, self.View4.bounds.size.height);
                             make.size.equalTo(realsize);
                         }];
                         [self.View4.superview layoutIfNeeded];
                     }];

---- 2018.7.12 補(bǔ)充

從渲染的幀率來看闸昨,使用約束進(jìn)行布局實質(zhì)上是會比較消耗資源的。
尤其是使用上文提到的 使用 masonry 進(jìn)行動畫薄风。

舉一個例子饵较,我們經(jīng)常用到的 IM 類場景(如 QQ,微信)這種高開銷的 tableView。聊天的內(nèi)容在不斷刷新遭赂,滑動后會加載新的頭像循诉,內(nèi)容等等。如果使用約束布局撇他,勢必面臨著重新渲染的情況茄猫。

這時候幀率 的卡頓會成為一個比較大的問題。

從經(jīng)驗上來總結(jié)逆粹,大開銷的場景下募疮,動畫和渲染,還是使用原始的frame布局來做僻弹。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末阿浓,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子蹋绽,更是在濱河造成了極大的恐慌芭毙,老刑警劉巖筋蓖,帶你破解...
    沈念sama閱讀 222,104評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異退敦,居然都是意外死亡粘咖,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,816評論 3 399
  • 文/潘曉璐 我一進(jìn)店門侈百,熙熙樓的掌柜王于貴愁眉苦臉地迎上來瓮下,“玉大人,你說我怎么就攤上這事钝域》砘担” “怎么了?”我有些...
    開封第一講書人閱讀 168,697評論 0 360
  • 文/不壞的土叔 我叫張陵例证,是天一觀的道長路呜。 經(jīng)常有香客問我,道長织咧,這世上最難降的妖魔是什么胀葱? 我笑而不...
    開封第一講書人閱讀 59,836評論 1 298
  • 正文 為了忘掉前任,我火速辦了婚禮笙蒙,結(jié)果婚禮上抵屿,老公的妹妹穿的比我還像新娘。我一直安慰自己捅位,他們只是感情好晌该,可當(dāng)我...
    茶點故事閱讀 68,851評論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著绿渣,像睡著了一般。 火紅的嫁衣襯著肌膚如雪燕耿。 梳的紋絲不亂的頭發(fā)上中符,一...
    開封第一講書人閱讀 52,441評論 1 310
  • 那天,我揣著相機(jī)與錄音誉帅,去河邊找鬼淀散。 笑死,一個胖子當(dāng)著我的面吹牛蚜锨,可吹牛的內(nèi)容都是我干的档插。 我是一名探鬼主播,決...
    沈念sama閱讀 40,992評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼亚再,長吁一口氣:“原來是場噩夢啊……” “哼郭膛!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起氛悬,我...
    開封第一講書人閱讀 39,899評論 0 276
  • 序言:老撾萬榮一對情侶失蹤则剃,失蹤者是張志新(化名)和其女友劉穎耘柱,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體棍现,經(jīng)...
    沈念sama閱讀 46,457評論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡调煎,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,529評論 3 341
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了己肮。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片士袄。...
    茶點故事閱讀 40,664評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖谎僻,靈堂內(nèi)的尸體忽然破棺而出娄柳,到底是詐尸還是另有隱情,我是刑警寧澤戈稿,帶...
    沈念sama閱讀 36,346評論 5 350
  • 正文 年R本政府宣布西土,位于F島的核電站,受9級特大地震影響鞍盗,放射性物質(zhì)發(fā)生泄漏需了。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 42,025評論 3 334
  • 文/蒙蒙 一般甲、第九天 我趴在偏房一處隱蔽的房頂上張望肋乍。 院中可真熱鬧,春花似錦敷存、人聲如沸墓造。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,511評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽觅闽。三九已至,卻和暖如春涮俄,著一層夾襖步出監(jiān)牢的瞬間蛉拙,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,611評論 1 272
  • 我被黑心中介騙來泰國打工彻亲, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留孕锄,地道東北人。 一個月前我還...
    沈念sama閱讀 49,081評論 3 377
  • 正文 我出身青樓苞尝,卻偏偏與公主長得像畸肆,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子宙址,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,675評論 2 359

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

  • 一轴脐、前言 關(guān)于蘋果的布局一直是我比較糾結(jié)的問題,是寫代碼來控制布局,還是使用storyboard來控制布局呢豁辉?以前...
    iplaycodex閱讀 2,454評論 0 1
  • iOS_autoLayout_Masonry 概述 Masonry是一個輕量級的布局框架與更好的包裝AutoLay...
    指尖的跳動閱讀 1,169評論 1 4
  • Masonry和FDTemplateLayoutCell搭配使用總結(jié) http://www.reibang.com...
    動感超人丶閱讀 75評論 0 0
  • 5月5日全國各地同期上映的印度電影《摔跤吧徽级,爸爸》獲得了幾乎所有影評人和觀影者的一致好評气破,這部勵志電影是根據(jù)印度國...
    凹現(xiàn)場閱讀 275評論 0 3
  • 姓名:陸振村~公司:浙江均泰建設(shè)有限公司 【日精進(jìn)打卡第47天】 【知~學(xué)習(xí)】 《六項精進(jìn)》大綱0遍 共64遍 《...
    陸振村閱讀 261評論 0 0