masonry使用技巧

masonry git地址:https://github.com/SnapKit/Masonry

本文主要會講到masonry英文文檔(見上面的git地址)中提及到的使用說明愚墓,以及個人使用過程中的一些經(jīng)驗,僅適用一些剛使用masonry的新手予权,大牛可以忽略浪册,當(dāng)然也可以進來指點扫腺。

一、常用的屬性與常量

1. MASViewAttribute 以對應(yīng)的系統(tǒng)類型

MASViewAttribute NSLayoutAttribute
view.mas_left NSLayoutAttributeLeft
view.mas_right NSLayoutAttributeRight
view.mas_top NSLayoutAttributeTop
view.mas_bottom NSLayoutAttributeBottom
view.mas_leading NSLayoutAttributeLeading
view.mas_trailing NSLayoutAttributeTrailing
view.mas_width NSLayoutAttributeWidth
view.mas_height NSLayoutAttributeHeight
view.mas_centerX NSLayoutAttributeCenterX
view.mas_centerY NSLayoutAttributeCenterY
view.mas_baseline NSLayoutAttributeBaseline

2.UIView

先來一波最為常用的使用方法村象,大家可以看一下大致語法笆环,下面會細講使用

//.分別設(shè)置各個相對邊距(superview為view的父類視圖,下同)
make.left.mas_equalTo(superView.mas_left).mas_offset(10);
make.right.mas_equalTo(superView.mas_right).mas_offset(-10);
make.top.mas_equalTo(superView.mas_top).mas_offset(10);
make.bottom.mas_equalTo(superView.mas_bottom).offset(-10);

//直接連接使用left大于等于每個值
make.left.mas_greaterThanOrEqualTo(10);

//設(shè)置寬和高
make.width.mas_equalTo(60);
make.height.mas_equalTo(60);

//.設(shè)置center和款高比
make.center.mas_equalTo(superView);
make.width.mas_equalTo(superView).multipliedBy(1.00/3);
make.height.mas_equalTo(superView).multipliedBy(0.25);

//.關(guān)于約束優(yōu)先級,此處要注意約束沖突的問題厚者,統(tǒng)一約束優(yōu)先級大的生效
make.left.mas_equalTo(100);
make.left.mas_equalTo(view.superview.mas_left).offset(10);
make.left.mas_equalTo(20).priority(700);
make.left.mas_equalTo(40).priorityHigh();
make.left.mas_equalTo(60).priorityMedium();
make.left.mas_equalTo(80).priorityLow();

//.如果你想讓view的(x坐標)左邊大于等于label的左邊躁劣,以下兩個約束的寫法效果一樣
 make.left.greaterThanOrEqualTo(label);
 make.left.greaterThanOrEqualTo(label.mas_left);

注:約束的鏈式寫法中,不包含其他相對的view時库菲,默認為其superview账忘,即make.left.mas_equalTo(100);等價于make.left.mas_equalTo(view.superview.mas_left).offset(10);make.left.mas_equalTo(view.superview).offset(10);

3. NSNumber

自動布局允許使用常量去設(shè)置寬或高,如果你想通過一個數(shù)字設(shè)置一個view的最小和最大的width,可以用equality blocks闪萄,如下:

//width >= 200 && width <= 400

make.width.greaterThanOrEqualTo(@200);

make.width.lessThanOrEqualTo(@400)

然而自動布局不允許對齊屬性的約束(如:left,right,centerY等)設(shè)置為常量值梧却,你可以使用NSNumber來設(shè)置相對于父類view這些約束屬性,如:

// creates view.left = view.superview.left + 10
make.left.lessThanOrEqualTo(@10)

如果你不想使用NSNumber來設(shè)置败去,也可以用如下結(jié)構(gòu)來創(chuàng)建你的約束放航,如:


make.top.mas_equalTo(42);

make.height.mas_equalTo(20);

make.size.mas_equalTo(CGSizeMake(50, 100));

make.edges.mas_equalTo(UIEdgeInsetsMake(10, 0, 10, 0));

make.left.mas_equalTo(view).mas_offset(UIEdgeInsetsMake(10, 0, 10, 0));

以上用法默認添加mas_前綴,如果你不想添加此前綴圆裕,但還想使用常量值設(shè)置約束广鳍,需要在導(dǎo)入Masonry頭文件前,設(shè)置宏定義MAS_SHORTHAND_GLOBALS吓妆,至于為什么赊时,去masonry代碼中搜索一下MAS_SHORTHAND_GLOBALS便知。

4. NSArray

用數(shù)組添加集中不同類的約束行拢,如:

make.height.equalTo(@[view1.mas_height, view2.mas_height]);

make.height.equalTo(@[view1, view2]);

make.left.equalTo(@[view1, @100, view3.right]);

二祖秒、約束的優(yōu)先級屬性

  • .priority允許你設(shè)置一個非常準確的的約束優(yōu)先級(0-1000)

  • .priorityHigh 相當(dāng)于系統(tǒng)的 UILayoutPriorityDefaultHigh

  • .priorityMedium 介于 high and low之間的優(yōu)先級

  • .priorityLow 相當(dāng)于系統(tǒng)的 UILayoutPriorityDefaultLow

注:默認通過mas_make添加的約束不設(shè)置優(yōu)先級時,默認都是最高(1000)

優(yōu)先級屬性可以放在約束鏈的末端使用舟奠,如:

make.left.greaterThanOrEqualTo(label.mas_left).with.priorityLow();
make.top.equalTo(label.mas_top).with.priority(600);

三竭缝、更加便利的約束方法

Masonry提供了一些便利的方法供我們同時創(chuàng)建多個不同的約束,他們被稱為MASCompositeConstraints沼瘫,如:

edges

// 使一個view的top, left, bottom, right 等于view2的

make.edges.equalTo(view2)抬纸;

//相對于superviewde上左下右邊距分別為5,10耿戚,15湿故,20

make.edges.equalTo(superview).insets(UIEdgeInsetsMake(5, 10, 15, 20))

size

// 使得寬度和高度大于等于 titleLabel

make.size.greaterThanOrEqualTo(titleLabel)

// 相對于superview寬度大100,高度小50

make.size.equalTo(superview).sizeOffset(CGSizeMake(100, -50))

center

//中心與button1對齊

make.center.equalTo(button1)

//水平方向中心相對向左偏移5膜蛔,豎直方向中心向下偏移10

make.center.equalTo(superview).centerOffset(CGPointMake(-5, 10))

你可以在約束鏈里添加相應(yīng)的view來增加代碼的可讀性:

// 除了top坛猪,所有的邊界與superview對齊

make.left.right.and.bottom.equalTo(superview);

make.top.equalTo(otherView);

四、關(guān)于如何修改約束

有時候皂股,你為了實現(xiàn)動畫或者移除替換一些約束時砚哆,你需要去修改一些已經(jīng)存在的約束,Masonry提供了一些不同的方法去更新約束屑墨,你也可以將多個約束存在數(shù)組里

1. References

你可以持有某個特定的約束躁锁,讓其成為成員變量或者屬性
//設(shè)置為公共或私接口

@property (nonatomic, strong) MASConstraint *topConstraint;

...

// 添加約束

[view1 mas_makeConstraints:^(MASConstraintMaker *make) {

self.topConstraint = make.top.equalTo(superview.mas_top).with.offset(padding.top);

make.left.equalTo(superview.mas_left).with.offset(padding.left);

}];

...

// 然后可以調(diào)用
//該約束移除
[self.topConstraint uninstall];
//重新設(shè)置value,最常用
self.topConstraint.mas_equalTo(20);
//該約束失效
[self.topConstraint deactivate];
//該約束生效
[self.topConstraint activate];

2. mas_updateConstraints

如果你只是想更新一下view對應(yīng)的約束,可以使用 mas_updateConstraints 方法代替 mas_makeConstraints方法
//這是蘋果推薦的添加或者更新約束的地方

// 在響應(yīng)setNeedsUpdateConstraints方法時卵史,這個方法會被調(diào)用多次

// 此方法會被UIKit內(nèi)部調(diào)用战转,或者在你觸發(fā)約束更新時調(diào)用

- (void)updateConstraints {

[self.growingButton mas_updateConstraints:^(MASConstraintMaker *make) {

make.center.equalTo(self);

make.width.equalTo(@(self.buttonSize.width)).priorityLow();

make.height.equalTo(@(self.buttonSize.height)).priorityLow();

make.width.lessThanOrEqualTo(self);

make.height.lessThanOrEqualTo(self);

}];

//調(diào)用super
[super updateConstraints];

}

3. mas_remakeConstraints

mas_updateConstraints只是去更新一些約束,然而有些時候修改一些約束值是沒用的,這時候mas_remakeConstraints就可以派上用場了

mas_remakeConstraints某些程度相似于mas_updateConstraints,但不同于mas_updateConstraints去更新約束值律胀,他會移除之前的view的所有約束闹蒜,然后再去添加約束

- (void)changeButtonPosition {

      [self.button mas_remakeConstraints:^(MASConstraintMaker *make) {

      make.size.equalTo(self.buttonSize);

     if (topLeft) {

          make.top.and.left.offset(10);

     } else {

     make.bottom.and.right.offset(-10); 

   }

  }];

五、在哪創(chuàng)建我的約束

貼一個官方說明的例子:

@implementation DIYCustomView

- (id)init {

self = [super init];

if (!self) return nil;

// --- Create your views here ---

self.button = [[UIButton alloc] init];

return self;

}

// tell UIKit that you are using AutoLayout

+ (BOOL)requiresConstraintBasedLayout {

return YES;

}

// this is Apple's recommended place for adding/updating constraints

- (void)updateConstraints {

// --- remake/update constraints here

[self.button remakeConstraints:^(MASConstraintMaker *make) {

make.width.equalTo(@(self.buttonSize.width));

make.height.equalTo(@(self.buttonSize.height));

}];

//according to apple super should be called at end of method

[super updateConstraints];

}

- (void)didTapButton:(UIButton *)button {

// --- Do your changes ie change variables that affect your layout etc ---

self.buttonSize = CGSize(200, 200);

// tell constraints they need updating

[self setNeedsUpdateConstraints];

}

六素标、Layout必備知識

AutoLayout關(guān)于更新的幾個方法的區(qū)別

  • setNeedsLayout:告知頁面需要更新险污,但是不會立刻開始更新致讥。執(zhí)行后會立刻調(diào)用layoutSubviews膀懈。

  • layoutIfNeeded:告知頁面布局立刻更新顿锰。所以一般都會和setNeedsLayout一起使用。如果希望立刻生成新的frame需要調(diào)用此方法启搂,利用這點一般布局動畫可以在更新布局后直接使用這個方法讓動畫生效硼控。

  • layoutSubviews:系統(tǒng)重寫布局

  • setNeedsUpdateConstraints:告知需要更新約束,但是不會立刻開始

  • updateConstraintsIfNeeded:告知立刻更新約束

  • updateConstraints:系統(tǒng)更新約束

七胳赌、使用tips

  • 給view添加約束時牢撼,必須已經(jīng)添加到其superview上面
  • 不需要設(shè)置view.translatesAutoresizingMaskIntoConstraints = NO;,masonry內(nèi)部已經(jīng)幫我設(shè)置過了
  • 手寫布局時疑苫,合理使用約束熏版,盡量約束沖突問題
  • 因為iOS中原點在左上角所以注意使用offset時注意right和bottom用負數(shù)

推薦兩個大牛寫的關(guān)于Masonry源碼解析的博客

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市捍掺,隨后出現(xiàn)的幾起案子撼短,更是在濱河造成了極大的恐慌,老刑警劉巖乡小,帶你破解...
    沈念sama閱讀 206,311評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異饵史,居然都是意外死亡满钟,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,339評論 2 382
  • 文/潘曉璐 我一進店門胳喷,熙熙樓的掌柜王于貴愁眉苦臉地迎上來湃番,“玉大人,你說我怎么就攤上這事吭露》痛椋” “怎么了?”我有些...
    開封第一講書人閱讀 152,671評論 0 342
  • 文/不壞的土叔 我叫張陵讲竿,是天一觀的道長泥兰。 經(jīng)常有香客問我,道長题禀,這世上最難降的妖魔是什么鞋诗? 我笑而不...
    開封第一講書人閱讀 55,252評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮迈嘹,結(jié)果婚禮上削彬,老公的妹妹穿的比我還像新娘全庸。我一直安慰自己,他們只是感情好融痛,可當(dāng)我...
    茶點故事閱讀 64,253評論 5 371
  • 文/花漫 我一把揭開白布壶笼。 她就那樣靜靜地躺著,像睡著了一般雁刷。 火紅的嫁衣襯著肌膚如雪覆劈。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,031評論 1 285
  • 那天安券,我揣著相機與錄音墩崩,去河邊找鬼。 笑死侯勉,一個胖子當(dāng)著我的面吹牛鹦筹,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播址貌,決...
    沈念sama閱讀 38,340評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼铐拐,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了练对?” 一聲冷哼從身側(cè)響起遍蟋,我...
    開封第一講書人閱讀 36,973評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎螟凭,沒想到半個月后虚青,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,466評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡螺男,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,937評論 2 323
  • 正文 我和宋清朗相戀三年棒厘,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片下隧。...
    茶點故事閱讀 38,039評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡奢人,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出淆院,到底是詐尸還是另有隱情何乎,我是刑警寧澤,帶...
    沈念sama閱讀 33,701評論 4 323
  • 正文 年R本政府宣布土辩,位于F島的核電站支救,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏拷淘。R本人自食惡果不足惜搂妻,卻給世界環(huán)境...
    茶點故事閱讀 39,254評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望辕棚。 院中可真熱鬧欲主,春花似錦邓厕、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,259評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至引几,卻和暖如春昧互,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背伟桅。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工敞掘, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人楣铁。 一個月前我還...
    沈念sama閱讀 45,497評論 2 354
  • 正文 我出身青樓玖雁,卻偏偏與公主長得像,于是被迫代替她去往敵國和親盖腕。 傳聞我的和親對象是個殘疾皇子赫冬,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,786評論 2 345

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

  • 一、前言 關(guān)于蘋果的布局一直是我比較糾結(jié)的問題溃列,是寫代碼來控制布局劲厌,還是使用storyboard來控制布局呢?以前...
    iplaycodex閱讀 2,435評論 0 1
  • Masonry是iOS在控件布局中經(jīng)常使用的一個輕量級框架听隐,Masonry讓NSLayoutConstraint使...
    丘比沙拉閱讀 3,179評論 2 19
  • Masonry是iOS在控件布局中經(jīng)常使用的一個輕量級框架补鼻,Masonry讓NSLayoutConstraint使...
    愛敲代碼的果果閱讀 1,873評論 0 2
  • Autolayout就像一個知情達理,善解人意的好姑娘雅任,可惜長相有點不堪入目风范,所以追求者寥寥無幾。所幸遇到了化妝大...
    小笨狼閱讀 23,957評論 28 227
  • 今天又多看到了一篇夜行日記椿访。 也許是因為他比較成熟乌企,所以反而很多事都藏著放在心里虑润。 當(dāng)他還在發(fā)夜行日記的時候成玫,我會...
    安褚閱讀 288評論 0 0