iOS Masonry詳解

現(xiàn)在iPhone手機(jī)屏幕越來越多, 屏幕適配也越來越重要. Masonry就是為屏幕適配而生的三方框架.

Masonry基礎(chǔ)API

mas_makeConstraints()    添加約束
mas_remakeConstraints()  移除之前的約束,重新添加新的約束
mas_updateConstraints()  更新約束,寫哪條更新哪條寇甸,其他約束不變

equalTo()       參數(shù)是對象類型舱禽,一般是視圖對象或者mas_width這樣的坐標(biāo)系對象
mas_equalTo()   和上面功能相同敢靡,參數(shù)可以傳遞基礎(chǔ)數(shù)據(jù)類型對象一汽,可以理解為比上面的API更強(qiáng)大

width()         用來表示寬度改览,例如代表view的寬度
mas_width()     用來獲取寬度的值亚兄。和上面的區(qū)別在于混稽,一個代表某個坐標(biāo)系對象,一個用來獲取坐標(biāo)系對象的值

更新約束和布局

- (void)updateConstraintsIfNeeded  調(diào)用此方法,如果有標(biāo)記為需要重新布局的約束匈勋,則立即進(jìn)行重新布局礼旅,內(nèi)部會調(diào)用updateConstraints方法
- (void)updateConstraints          重寫此方法,內(nèi)部實(shí)現(xiàn)自定義布局過程
- (BOOL)needsUpdateConstraints     當(dāng)前是否需要重新布局洽洁,內(nèi)部會判斷當(dāng)前有沒有被標(biāo)記的約束
- (void)setNeedsUpdateConstraints  標(biāo)記需要進(jìn)行重新布局

Masonry示例代碼

Masonry本質(zhì)上就是對系統(tǒng)AutoLayout進(jìn)行的封裝痘系,包括里面很多的API,都是對系統(tǒng)API進(jìn)行了一次二次包裝饿自。
typedef NS_OPTIONS(NSInteger, MASAttribute) {
    MASAttributeLeft = 1 << NSLayoutAttributeLeft,
    MASAttributeRight = 1 << NSLayoutAttributeRight,
    MASAttributeTop = 1 << NSLayoutAttributeTop,
    MASAttributeBottom = 1 << NSLayoutAttributeBottom,
    MASAttributeLeading = 1 << NSLayoutAttributeLeading,
    MASAttributeTrailing = 1 << NSLayoutAttributeTrailing,
    MASAttributeWidth = 1 << NSLayoutAttributeWidth,
    MASAttributeHeight = 1 << NSLayoutAttributeHeight,
    MASAttributeCenterX = 1 << NSLayoutAttributeCenterX,
    MASAttributeCenterY = 1 << NSLayoutAttributeCenterY,
    MASAttributeBaseline = 1 << NSLayoutAttributeBaseline,
};

常用方法

設(shè)置內(nèi)邊距
/** 
 設(shè)置yellow視圖和self.view等大汰翠,并且有10的內(nèi)邊距。
 注意根據(jù)UIView的坐標(biāo)系昭雌,下面right和bottom進(jìn)行了取反复唤。所以不能寫成下面這樣,否則right烛卧、bottom這兩個方向會出現(xiàn)問題佛纫。
 make.edges.equalTo(self.view).with.offset(10);
 
 除了下面例子中的offset()方法,還有針對不同坐標(biāo)系的centerOffset()总放、sizeOffset()呈宇、valueOffset()之類的方法。
 */
[self.yellowView mas_makeConstraints:^(MASConstraintMaker *make) {
    make.left.equalTo(self.view).with.offset(10);
    make.top.equalTo(self.view).with.offset(10);
    make.right.equalTo(self.view).with.offset(-10);
    make.bottom.equalTo(self.view).with.offset(-10);
}];
通過insets簡化設(shè)置內(nèi)邊距的方式
// 下面的方法和上面例子等價局雄,區(qū)別在于使用insets()方法甥啄。
[self.blueView mas_makeConstraints:^(MASConstraintMaker *make) {
    // 下、右不需要寫負(fù)號炬搭,insets方法中已經(jīng)為我們做了取反的操作了蜈漓。
    make.edges.equalTo(self.view).with.insets(UIEdgeInsetsMake(10, 10, 10, 10));
}];
更新約束
// 設(shè)置greenView的center和size,這樣就可以達(dá)到簡單進(jìn)行約束的目的
[self.greenView mas_makeConstraints:^(MASConstraintMaker *make) {
    make.center.equalTo(self.view);
    // 這里通過mas_equalTo給size設(shè)置了基礎(chǔ)數(shù)據(jù)類型的參數(shù)尚蝌,參數(shù)為CGSize的結(jié)構(gòu)體
    make.size.mas_equalTo(CGSizeMake(300, 300));
}];

// 為了更清楚的看出約束變化的效果迎变,在顯示兩秒后更新約束。
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.f * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
    // 指定更新size飘言,其他約束不變衣形。
    [self.greenView mas_updateConstraints:^(MASConstraintMaker *make) {
        make.size.mas_equalTo(CGSizeMake(100, 100));
    }];
});
大于等于和小于等于某個值的約束
[self.textLabel mas_makeConstraints:^(MASConstraintMaker *make) {
    make.center.equalTo(self.view);
    // 設(shè)置寬度小于等于200
    make.width.lessThanOrEqualTo(@200);
    // 設(shè)置高度大于等于10
    make.height.greaterThanOrEqualTo(@(10));
}];

self.textLabel.text = @"這是測試的字符串。能看到1姿鸿、2谆吴、3個步驟,第一步當(dāng)然是上傳照片了苛预,要上傳正面近照哦句狼。上傳后,網(wǎng)站會自動識別你的面部热某,如果覺得識別的不準(zhǔn)腻菇,你還可以手動修改一下胳螟。左邊可以看到16項(xiàng)修改參數(shù),最上面是整體修改筹吐,你也可以根據(jù)自己的意愿單獨(dú)修改某項(xiàng)糖耸,將鼠標(biāo)放到選項(xiàng)上面,右邊的預(yù)覽圖會顯示相應(yīng)的位置丘薛。";

textLabel只需要設(shè)置一個屬性即可

self.textLabel.numberOfLines = 0;
使用基礎(chǔ)數(shù)據(jù)類型當(dāng)做參數(shù)
/** 
 如果想使用基礎(chǔ)數(shù)據(jù)類型當(dāng)做參數(shù)嘉竟,Masonry為我們提供了"mas_xx"格式的宏定義。
 這些宏定義會將傳入的基礎(chǔ)數(shù)據(jù)類型轉(zhuǎn)換為NSNumber類型洋侨,這個過程叫做封箱(Auto Boxing)舍扰。

 "mas_xx"開頭的宏定義,內(nèi)部都是通過MASBoxValue()函數(shù)實(shí)現(xiàn)的希坚。
 這樣的宏定義主要有四個边苹,分別是mas_equalTo()、mas_offset()和大于等于吏够、小于等于四個勾给。
 */
[self.redView mas_makeConstraints:^(MASConstraintMaker *make) {
    make.center.equalTo(self.view);
    make.width.mas_equalTo(100);
    make.height.mas_equalTo(100);
}];
設(shè)置約束優(yōu)先級
/** 
 Masonry為我們提供了三個默認(rèn)的方法滩报,priorityLow()锅知、priorityMedium()、priorityHigh()脓钾,這三個方法內(nèi)部對應(yīng)著不同的默認(rèn)優(yōu)先級售睹。
 除了這三個方法,我們也可以自己設(shè)置優(yōu)先級的值可训,可以通過priority()方法來設(shè)置昌妹。
 */
[self.redView mas_makeConstraints:^(MASConstraintMaker *make) {
    make.center.equalTo(self.view);
    make.width.equalTo(self.view).priorityLow();
    make.width.mas_equalTo(20).priorityHigh();
    make.height.equalTo(self.view).priority(200);
    make.height.mas_equalTo(100).priority(1000);
}];
Masonry也幫我們定義好了一些默認(rèn)的優(yōu)先級常量,分別對應(yīng)著不同的數(shù)值握截,優(yōu)先級最大數(shù)值是1000飞崖。
static const MASLayoutPriority MASLayoutPriorityRequired = UILayoutPriorityRequired;
static const MASLayoutPriority MASLayoutPriorityDefaultHigh = UILayoutPriorityDefaultHigh;
static const MASLayoutPriority MASLayoutPriorityDefaultMedium = 500;
static const MASLayoutPriority MASLayoutPriorityDefaultLow = UILayoutPriorityDefaultLow;
static const MASLayoutPriority MASLayoutPriorityFittingSizeLevel = UILayoutPriorityFittingSizeLevel;
設(shè)置約束比例
// 設(shè)置當(dāng)前約束值乘以多少,例如這個例子是redView的寬度是self.view寬度的0.2倍谨胞。
[self.redView mas_makeConstraints:^(MASConstraintMaker *make) {
    make.center.equalTo(self.view);
    make.height.mas_equalTo(30);
    make.width.equalTo(self.view).multipliedBy(0.2);
}];

小練習(xí)

子視圖等高/等寬練習(xí)
     /**
     下面的例子是通過給equalTo()方法傳入一個數(shù)組固歪,設(shè)置數(shù)組中子視圖及當(dāng)前make對應(yīng)的視圖之間等高。
     
     需要注意的是胯努,下面block中設(shè)置邊距的時候牢裳,應(yīng)該用insets來設(shè)置,而不是用offset叶沛。
     因?yàn)橛胦ffset設(shè)置right和bottom的邊距時蒲讯,這兩個值應(yīng)該是負(fù)數(shù),所以如果通過offset來統(tǒng)一設(shè)置值會有問題灰署。
     */
    
    CGFloat padding = 10;
    
    UIView *redView = [[UIView alloc]init];
    redView.backgroundColor = [UIColor redColor];
    [self.view addSubview:redView];
    
    UIView *blueView = [[UIView alloc]init];
    blueView.backgroundColor = [UIColor blueColor];
    [self.view addSubview:blueView];
    
    UIView *yellowView = [[UIView alloc]init];
    yellowView.backgroundColor = [UIColor yellowColor];
    [self.view addSubview:yellowView];

    /**********  等高   ***********/
    [redView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.left.right.top.equalTo(self.view).insets(UIEdgeInsetsMake(padding, padding, 0, padding));
        make.bottom.equalTo(blueView.mas_top).offset(-padding);
    }];
    [blueView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.left.right.equalTo(self.view).insets(UIEdgeInsetsMake(0, padding, 0, padding));
        make.bottom.equalTo(yellowView.mas_top).offset(-padding);
    }];

    /**
     下面設(shè)置make.height的數(shù)組是關(guān)鍵判帮,通過這個數(shù)組可以設(shè)置這三個視圖高度相等局嘁。其他例如寬度之類的,也是類似的方式晦墙。
     */
    [yellowView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.left.right.bottom.equalTo(self.view).insets(UIEdgeInsetsMake(0, padding, padding, padding));
        make.height.equalTo(@[blueView, redView]);
    }];

    /**********  等寬   ***********/
    [redView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.top.left.bottom.equalTo(self.view).insets(UIEdgeInsetsMake(padding, padding, padding, 0));
        make.right.equalTo(blueView.mas_left).offset(-padding);
    }];
    [blueView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.top.bottom.equalTo(self.view).insets(UIEdgeInsetsMake(padding, 0, padding, 0));
        make.right.equalTo(yellowView.mas_left).offset(-padding);
    }];
    [yellowView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.top.bottom.right.equalTo(self.view).insets(UIEdgeInsetsMake(padding, 0, padding, padding));
        make.width.equalTo(@[redView, blueView]);
    }];
等高

等寬
子視圖垂直居中練習(xí)
    CGFloat padding = 10;
    
    UIView *redView = [[UIView alloc]init];
    redView.backgroundColor = [UIColor redColor];
    [self.view addSubview:redView];
    
    UIView *blueView = [[UIView alloc]init];
    blueView.backgroundColor = [UIColor blueColor];
    [self.view addSubview:blueView];
    
    [redView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.centerY.equalTo(self.view);
        make.left.equalTo(self.view).mas_offset(padding);
        make.right.equalTo(blueView.mas_left).mas_offset(-padding);
        //make.width.equalTo(blueView);
        make.height.mas_equalTo(150);
    }];
    
    [blueView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.centerY.equalTo(self.view);
        make.right.equalTo(self.view).mas_offset(-padding);
        make.width.equalTo(redView);
        make.height.mas_equalTo(150);
    }];
子視圖垂直居中練習(xí)
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末导狡,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子偎痛,更是在濱河造成了極大的恐慌旱捧,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,888評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件踩麦,死亡現(xiàn)場離奇詭異枚赡,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)谓谦,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,677評論 3 399
  • 文/潘曉璐 我一進(jìn)店門贫橙,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人反粥,你說我怎么就攤上這事卢肃。” “怎么了才顿?”我有些...
    開封第一講書人閱讀 168,386評論 0 360
  • 文/不壞的土叔 我叫張陵莫湘,是天一觀的道長。 經(jīng)常有香客問我郑气,道長幅垮,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,726評論 1 297
  • 正文 為了忘掉前任尾组,我火速辦了婚禮忙芒,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘讳侨。我一直安慰自己呵萨,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,729評論 6 397
  • 文/花漫 我一把揭開白布跨跨。 她就那樣靜靜地躺著潮峦,像睡著了一般。 火紅的嫁衣襯著肌膚如雪歹叮。 梳的紋絲不亂的頭發(fā)上跑杭,一...
    開封第一講書人閱讀 52,337評論 1 310
  • 那天,我揣著相機(jī)與錄音咆耿,去河邊找鬼德谅。 笑死,一個胖子當(dāng)著我的面吹牛萨螺,可吹牛的內(nèi)容都是我干的窄做。 我是一名探鬼主播愧驱,決...
    沈念sama閱讀 40,902評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼椭盏!你這毒婦竟也來了组砚?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,807評論 0 276
  • 序言:老撾萬榮一對情侶失蹤掏颊,失蹤者是張志新(化名)和其女友劉穎糟红,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體乌叶,經(jīng)...
    沈念sama閱讀 46,349評論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡盆偿,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,439評論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了准浴。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片事扭。...
    茶點(diǎn)故事閱讀 40,567評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖乐横,靈堂內(nèi)的尸體忽然破棺而出求橄,到底是詐尸還是另有隱情,我是刑警寧澤葡公,帶...
    沈念sama閱讀 36,242評論 5 350
  • 正文 年R本政府宣布罐农,位于F島的核電站,受9級特大地震影響匾南,放射性物質(zhì)發(fā)生泄漏啃匿。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,933評論 3 334
  • 文/蒙蒙 一蛆楞、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧夹厌,春花似錦豹爹、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,420評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至或南,卻和暖如春孩等,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背采够。 一陣腳步聲響...
    開封第一講書人閱讀 33,531評論 1 272
  • 我被黑心中介騙來泰國打工肄方, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人蹬癌。 一個月前我還...
    沈念sama閱讀 48,995評論 3 377
  • 正文 我出身青樓权她,卻偏偏與公主長得像虹茶,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子隅要,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,585評論 2 359

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