Masonry2

Masonry簡介 http://www.lxweimin.com/p/e3162f3c61fa
Masonry
是一個輕量級的布局框架,它擁有自己的描述語法(采用更優(yōu)雅的鏈?zhǔn)秸Z法封裝)來自動布局,具有很好可讀性且同時支持iOS和Max OS X
等??傊?,對于側(cè)重寫代碼的coder,請你慢慢忘記Frame
,喜歡Masonry

使用前的準(zhǔn)備
若是你對于自動布局很熟練的話,再接觸這個第三方Masonry
很容易上手的,對UI界面顯示的控件的約束本質(zhì)都是相同的,現(xiàn)在呢,我一般都是喜歡在控制器里導(dǎo)入#import "Masonry.h"
之前再添加兩個宏,來提高App的開發(fā)效率。

//1. 對于約束參數(shù)可以省去"mas_"#define MAS_SHORTHAND

//2. 對于默認(rèn)的約束參數(shù)自動裝箱#define MAS_SHORTHAND_GLOBALS

即:需要我們導(dǎo)入的框架與宏如下
//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" //宏必須添加在頭文件前面

添加約束前提:被約束的必須有父控件,其中約束項都必須是UIView或子類的實例
。

約束的屬性
在此我就列舉幾個可能不太熟悉的吧
@property (nonatomic, strong, readonly) MASConstraint *leading; //首部@property (nonatomic, strong, readonly) MASConstraint *trailing; //尾部@property (nonatomic, strong, readonly) MASConstraint *baseline; //文本基線

約束的三種方法
/** //這個方法只會添加新的約束 [blueView mas_makeConstraints:^(MASConstraintMaker *make) { }]; // 這個方法會將以前的所有約束刪掉,添加新的約束 [blueView mas_remakeConstraints:^(MASConstraintMaker *make) { }]; // 這個方法將會覆蓋以前的某些特定的約束 [blueView mas_updateConstraints:^(MASConstraintMaker *make) { }]; */`

常見約束的各種類型
/** 1.尺寸:width、height、size 2.邊界:left、leading、right、trailing、top、bottom 3.中心點:center、centerX、centerY 4.邊界:edges 5.偏移量:offset、insets、sizeOffset、centerOffset 6.priority()約束優(yōu)先級(0~1000),multipler乘因數(shù), dividedBy除因數(shù) */

Masonry約束易忽略的技術(shù)點
使用Masonry
不需要設(shè)置控件的translatesAutoresizingMaskIntoConstraints
屬性為NO
;防止block
中的循環(huán)引用,使用弱引用(這是錯誤觀點),在這里block
是局部的引用,block
內(nèi)部引用self
不會造成循環(huán)引用的__weak typeof (self) weakSelf = self
;(沒必要的寫法)

Masonry約束控件出現(xiàn)沖突的問題
當(dāng)約束沖突發(fā)生的時候,我們可以設(shè)置view的key來定位是哪個viewredView.mas_key = @"redView";greenView.mas_key = @"greenView";blueView.mas_key = @"blueView";若是覺得這樣一個個設(shè)置比較繁瑣,怎么辦呢,Masonry則提供了批量設(shè)置的宏MASAttachKeysMASAttachKeys(redView,greenView,blueView); //一句代碼即可全部設(shè)置

約束iconView
距離各個邊距為30
[iconView makeConstraints:^(MASConstraintMaker *make) { make.edges.equalTo(self.view).insets(UIEdgeInsetsMake(30, 30, 30, 30)); }];

equalTo 和 mas_equalTo的區(qū)別

define mas_equalTo(...) equalTo(MASBoxValue((VA_ARGS)))#define mas_greaterThanOrEqualTo(...) greaterThanOrEqualTo(MASBoxValue((VA_ARGS)))#define mas_lessThanOrEqualTo(...) lessThanOrEqualTo(MASBoxValue((VA_ARGS)))#define mas_offset(...) valueOffset(MASBoxValue((VA_ARGS)))

得出結(jié)論:mas_equalTo
只是對其參數(shù)進(jìn)行了一個BOX
(裝箱) 操作,目前支持的類型:數(shù)值類型(NSNumber)、 點(CGPoint)、大?。–GSize)、邊距(UIEdgeInsets)
,而equalTo:
這個方法不會對參數(shù)進(jìn)行包裝。
//常見約束的寫法 這里太簡單了 ,就不備注了[iconView makeConstraints:^(MASConstraintMaker *make) { make.right.equalTo(self.view).offset(-30); make.top.equalTo(self.view).offset(30); make.height.width.equalTo(100); //== make.size.equalTo(100); //make.size.mas_equalTo(self.view).multipliedBy(0.5); //make.top.greaterThanOrEqualTo(self.view).offset(padding); }];

[redView mas_makeConstraints:^(MASConstraintMaker *make) { make.top.equalTo(superview.mas_top).with.offset(10); //with 增強可讀性 make.left.equalTo(greenView.mas_right).and.offset(10); //and 增強可讀性 make.bottom.equalTo(blueView.mas_top).offset(-10); make.right.equalTo(superview.mas_right).offset(-10); make.width.equalTo(greenView.mas_width); make.height.equalTo(@[greenView, blueView]); //約束參數(shù)相同可以通過數(shù)組 }];

更新約束的問題
例如:控制器有個按鈕,若是點擊按鈕,則按鈕本身的大小、位置會隨機改變
監(jiān)聽按鈕點擊[self.btn addTarget:self action:@selector(didClickBtn:) forControlEvents:UIControlEventTouchUpInside];

處理事件
(void) didClickBtn:(UIButton *)button { self.btnSize = CGSizeMake(self.btnSize.width * 1.3, self.btnSize.height * 1.3); //設(shè)置一個屬性(btnSize)保存其大小的變化 //1.告知需要更新約束,但不會立刻開始,系統(tǒng)然后調(diào)用updateConstraints [self setNeedsUpdateConstraints]; //2.告知立刻更新約束,系統(tǒng)立即調(diào)用updateConstraints [self updateConstraintsIfNeeded]; //3.這里動畫當(dāng)然可以取消,具體看項目的需求 //系統(tǒng)block內(nèi)引用不會導(dǎo)致循環(huán)引用,block結(jié)束就會釋放引用對象 [UIView animateWithDuration:0.4 animations:^{ [self layoutIfNeeded]; //告知頁面立刻刷新,系統(tǒng)立即調(diào)用updateConstraints }];}

蘋果官方建議:添加/更新約束在這個方法(updateConstraints)
內(nèi)

// this is Apple's recommended place for adding/updating constraints- (void)updateConstraints { //更新約束 [self.btn 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); }]; //according to apple super should be called at end of method //最后必須調(diào)用父類的更新約束 [super updateConstraints];}

設(shè)置requiresConstraintBasedLayout
為YES

  • (BOOL)requiresConstraintBasedLayout{ return YES ; //重寫這個方法 若視圖基于自動布局的}

重置約束的問題
對于控件的重新約束,則之前的約束都是無效的,步驟都更新約束一樣的,只是在updateConstraints
方法內(nèi)的約束方法改為了remakeConstraints
,直接貼代碼吧(仍以按鈕為例,其他原理都是相同的)
//首先監(jiān)聽按鈕[self.btn addTarget:self action:@selector(didClickBtn:) forControlEvents:UIControlEventTouchUpInside];//處理事件- (void) didClickBtn :(UIButton )button{ (...) //觸發(fā)條件 [self setNeedsUpdateConstraints]; [self updateConstraintsIfNeeded]; /* * 動畫展示變化 - 這句代碼可有可無,參考項目具體的需求 * [UIView animateWithDuration:0.4 animations:^{ * [self layoutIfNeeded]; * }]; */}//重置約束- (void)updateConstraints { [self.btn remakeConstraints:^(MASConstraintMaker *make) { ..... }]; [super updateConstraints]; }+ (BOOL)requiresConstraintBasedLayout{ return YES ; //重寫這個方法 若視圖基于自動布局的}

多個(2個以上)控件的等間隔排序顯示
首先介紹2個函數(shù)
/** * axisType 軸線方向 * fixedSpacing 間隔大小 * fixedItemLength 每個控件的固定長度/寬度 * leadSpacing 頭部間隔 * tailSpacing 尾部間隔 * *///1. 等間隔排列 - 多個控件間隔固定,控件長度/寬度變化- (void)mas_distributeViewsAlongAxis:(MASAxisType)axisTypewithFixedSpacing:(CGFloat)fixedSpacing leadSpacing:(CGFloat)leadSpacingtailSpacing:(CGFloat)tailSpacing;//2. 等間隔排列 - 多個固定大小固定,間隔空隙變化- (void)mas_distributeViewsAlongAxis:(MASAxisType)axisTypewithFixedItemLength:(CGFloat)fixedItemLengthleadSpacing:(CGFloat)leadSpacingtailSpacing:(CGFloat)tailSpacing;

//首先添加5個視圖 NSMutableArray *array = [NSMutableArray new]; for (int i = 0; i < 5; i ++) { UIView *view = [UIView new]; view.backgroundColor = [UIColor greenColor]; [self addSubview:view]; [array addObject:view]; //保存添加的控件 }//水平方向控件間隔固定等間隔[array mas_distributeViewsAlongAxis:MASAxisTypeHorizontal withFixedSpacing:15 leadSpacing:10 tailSpacing:10]; [array makeConstraints:^(MASConstraintMaker *make) { make.top.equalTo(50); make.height.equalTo(70); }];//水平方向?qū)挾裙潭ǖ乳g隔[array mas_distributeViewsAlongAxis:MASAxisTypeHorizontal withFixedItemLength:70 leadSpacing:10 tailSpacing:10]; [array makeConstraints:^(MASConstraintMaker *make) { //數(shù)組額你不必須都是view make.top.equalTo(50); make.height.equalTo(70); }];

水平方向等間隔.png

水平方向控件寬度固定等間隔.png

多行l(wèi)abel的約束問題
對于UILabel
文字內(nèi)容多的問題,個人覺得Masonry
約束設(shè)置的非常簡單優(yōu)雅,在此非常感謝Masonry
的作者@Robert Payne
//創(chuàng)建label self.label = [UILabel new]; self.label.numberOfLines = 0; self.label.lineBreakMode = NSLineBreakByTruncatingTail; self.label.text = @"有的人,沒事時喜歡在朋友圈里到處點贊,東評論一句西評論一句,比誰都有存在感。等你有事找他了,他就立刻變得很忙,讓你再也找不著。真正的朋友,平常很少聯(lián)系??梢坏┠阌錾狭穗y處,他會立刻回復(fù)你的消息,第一時間站出來幫你。所謂的存在感,不是你有沒有出現(xiàn),而是你的出現(xiàn)有沒有價值。存在感,不是刷出來的,也不是說出來的。有存在感,未必是要個性鋒芒畢露、甚至鋒利扎人。翩翩君子,溫潤如玉,真正有存在感的人,反而不會刻意去強調(diào)他的存在感。他的出現(xiàn),永遠(yuǎn)都恰到好處。我所欣賞的存在感,不是長袖善舞巧言令色,而是對他人的真心關(guān)照;不是鋒芒畢露計較勝負(fù),而是讓人相處得舒服;不是時時刻刻聒噪不休,而是關(guān)鍵時刻能挺身而出。別總急著出風(fēng)頭,希望你能有恰到好處的存在感。"; [self addSubview: self.label]; [self.label makeConstraints:^(MASConstraintMaker *make) { make.left.top.equalTo(10); make.right.equalTo(-10); }];//添加約束- (void)layoutSubviews { //1. 執(zhí)行 [super layoutSubviews]; [super layoutSubviews]; //2. 設(shè)置preferredMaxLayoutWidth: 多行l(wèi)abel約束的完美解決 self.label.preferredMaxLayoutWidth = [UIScreen mainScreen].bounds.size.width - 20; //3. 設(shè)置preferredLayoutWidth后,需要再次執(zhí)行 [super layoutSubviews]; //其實在實際中這步不寫,也不會出錯,官方解釋是說設(shè)置preferredLayoutWidth后需要重新計算并布局界面,所以這步最好執(zhí)行 [super layoutSubviews];}

多行l(wèi)abel約束.png

UIScrollView的問題
原理同自動布局一樣 UIScrollView上添加UIViewUIView上添加需要顯示的控件 UIScrollView滾動高度取決于顯示控件的總高度對子控件做好約束,可達(dá)到控制UIView的大小

//創(chuàng)建滾動視圖 UIScrollView *scrollView = [UIScrollView new]; self.scrollView = scrollView; scrollView.backgroundColor = [UIColor grayColor]; [self addSubview:scrollView]; [self.scrollView makeConstraints:^(MASConstraintMaker *make) { make.edges.equalTo(self); }]; [self setUpContentView]; //添加內(nèi)容視圖- (void)setUpContentView { //約束UIScrollView上contentView UIView *contentView = [UIView new]; [self.scrollView addSubview:contentView]; [contentView makeConstraints:^(MASConstraintMaker *make) { make.edges.equalTo(self.scrollView); make.width.equalTo(self.scrollView); //此處必填 - 關(guān)鍵點 }]; //添加控件到contentView,約束原理與自動布局相同 UIView *lastView; CGFloat height = 30; for (int i = 0; i <1 5; i ++) { UIView *view = UIView.new; view.backgroundColor = [UIColor colorWithRed:arc4random() % 255 / 256.0 green:arc4random() % 255 / 256.0 blue:arc4random() % 255 / 256.0 alpha:1.0]; [contentView addSubview:view]; [view makeConstraints:^(MASConstraintMaker *make) { make.top.equalTo(lastView ? lastView.bottom : @0); make.left.equalTo(0); make.width.equalTo(contentView.width); make.height.equalTo(height); }]; height += 30; lastView = view; } [contentView makeConstraints:^(MASConstraintMaker *make) { make.bottom.equalTo(lastView.bottom); }];}

scrollView的約束設(shè)置.png

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,117評論 6 537
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,860評論 3 423
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事?!?“怎么了?”我有些...
    開封第一講書人閱讀 177,128評論 0 381
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,291評論 1 315
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 72,025評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,421評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,477評論 3 444
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,642評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,177評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 40,970評論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,157評論 1 371
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,717評論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 44,410評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,821評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,053評論 1 289
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,896評論 3 395
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 48,157評論 2 375

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