等間距布局 - 從0開始說一下masonry的使用

接上篇文章從0開始說一下masonry的使用 - 基本使用

以下將從幾個(gè)方面說一下如何使用Masonry

  1. 怎樣添加約束才能滿足一個(gè)View, 及masonry的基本使用
  2. 如何使用masonry等間隙排布幾個(gè)View
  3. 更新約束動(dòng)畫
  4. ScrolView如何布局
  5. tableViewCell高度動(dòng)態(tài)變化

2. 如何使用masonry等間隙排布幾個(gè)View

先直接上圖, 最終要實(shí)現(xiàn)這樣一個(gè)布局

Paste_Image.png

這里一共三部分, 最上面黃色的中間藍(lán)色的都是用了masonry提供的方法, 適用于等大小的View等間距布局, 最下面的綠色View是自己自己封裝的分類, 適用于不等大VIew的等間距布局, 來自于這邊經(jīng)典的文章Masonry介紹與使用實(shí)踐:快速上手Autolayout

接下來分別說一下這三部分

第一部分, 直接上代碼

Paste_Image.png
    //在紅色View里面放三個(gè)正方形View, 等間距為10
    NSInteger padding = 10;
    UIView *yellowView1 = [[UIView alloc] init];
    yellowView1.backgroundColor = [UIColor yellowColor];
    [redView addSubview:yellowView1];
    
    UIView *yellowView2 = [[UIView alloc] init];
    yellowView2.backgroundColor = [UIColor yellowColor];
    [redView addSubview:yellowView2];
    
    UIView *yellowView3 = [[UIView alloc] init];
    yellowView3.backgroundColor = [UIColor yellowColor];
    [redView addSubview:yellowView3];
    
    [@[yellowView1, yellowView2, yellowView3] mas_distributeViewsAlongAxis:MASAxisTypeHorizontal withFixedSpacing:padding leadSpacing:padding tailSpacing:padding];
    
    [@[yellowView1, yellowView2, yellowView3] mas_makeConstraints:^(MASConstraintMaker *make) {
        make.top.equalTo(redView).offset(10);
        make.height.mas_equalTo(yellowView3.mas_width);
    }];

masonry提供了這樣一個(gè)方法:

/**
 *  確定間距等間距布局
 *
 *  @param axisType     布局方向
 *  @param fixedSpacing 兩個(gè)item之間的間距(最左面的item和左邊, 最右邊item和右邊都不是這個(gè))
 *  @param leadSpacing  第一個(gè)item到父視圖邊距
 *  @param tailSpacing  最后一個(gè)item到父視圖邊距
 */
- (void)mas_distributeViewsAlongAxis:(MASAxisType)axisType withFixedSpacing:(CGFloat)fixedSpacing leadSpacing:(CGFloat)leadSpacing tailSpacing:(CGFloat)tailSpacing;

所以也就知道了, 將fixedSpacing, leadSpacing, tailSpacing都賦值同一個(gè)間距, 數(shù)組內(nèi)的的View就會(huì)自動(dòng)計(jì)算出寬度, 完成水平方向的布局.

要注意的是, 這個(gè)方法僅僅完成了水平方向的布局, 如果想確定這幾個(gè)View的位置, 還需要指定豎直方向位置和高度, 這里可以用數(shù)組直接調(diào)用 mas_makeConstraints:^(MASConstraintMaker *make){} 完成布局.

第二部分, 代碼如下:

Paste_Image.png
    //在紅色View里面放三個(gè)正方形藍(lán)色View, 寬度均為30, 間隙一樣大
    NSMutableArray *blueViews = [NSMutableArray array];
    for (NSInteger i = 0; i < 3; i++) {
        UIView *blueView = [[UIView alloc] init];
        blueView.backgroundColor = [UIColor blueColor];
        [redView addSubview:blueView];
        [blueViews addObject:blueView];
    }
    CGFloat padding2 = (300 - 3 * 30) / 4;
    [blueViews mas_distributeViewsAlongAxis:MASAxisTypeHorizontal withFixedItemLength:30 leadSpacing:padding2 tailSpacing:padding2];
    [blueViews mas_makeConstraints:^(MASConstraintMaker *make) {
        make.centerY.equalTo(redView);
        UIView *blueView = (UIView *)blueViews[0];
        make.height.mas_equalTo(blueView.mas_width);
    }];

這里用到了masonry提供的另一個(gè)方法, 和上一個(gè)方法基本完全一樣

/**
 *  distribute with fixed item size
 *
 *  @param axisType  布局方向  
 *  @param fixedItemLength 每個(gè)item的布局方向的長度
 *  @param leadSpacing  第一個(gè)item到父視圖邊距
 *  @param tailSpacing  最后一個(gè)item到父視圖邊距
 */
- (void)mas_distributeViewsAlongAxis:(MASAxisType)axisType withFixedItemLength:(CGFloat)fixedItemLength leadSpacing:(CGFloat)leadSpacing tailSpacing:(CGFloat)tailSpacing;

區(qū)別就是這里除了布局方向, 第一個(gè)和最后一個(gè)View的邊距, 這里需要指定的是每個(gè)item的長度, 自動(dòng)計(jì)算間隙, 所以這個(gè)要實(shí)現(xiàn)等間距, 其實(shí)是要通過item的數(shù)量, 以及父視圖的寬度先計(jì)算出間距, 然后賦值給, leadSpacing和tailSpacing, 比如CGFloat padding2 = (300 - 3 * 30) / 4; 這里的300就是父視圖的寬度, 30是指定的每個(gè)item的寬度, 這樣計(jì)算好就可以保證, leadSpacing, tailSpacing, 和item之間的間距相同, 實(shí)現(xiàn)布局.

同樣這個(gè)方法完成了水平方向的布局, 還需要完成豎直方向的布局.

第三部分, 代碼如下:

Paste_Image.png
    //在紅色View里面放三個(gè)大小不一樣的綠色正方形, 間隙等大, masonry并沒提供相關(guān)方法
    NSMutableArray *greenViews = [NSMutableArray array];
    for (NSInteger i = 0; i < 3; i++) {
        UIView *greenView = [[UIView alloc] init];
        greenView.backgroundColor = [UIColor greenColor];
        [redView addSubview:greenView];
        [greenViews addObject:greenView];
        [greenView mas_makeConstraints:^(MASConstraintMaker *make) {
            make.bottom.equalTo(redView).offset(-10);
            make.width.mas_equalTo(i*20 + 20);
            make.height.mas_equalTo(greenView.mas_width);
        }];
    }
    [redView distributeSpacingHorizontallyWith:greenViews];

首先在for循環(huán)內(nèi) , 完成了底部位置, 寬, 高的布局, 還缺少水平方向的位置, 即還要確定每個(gè)view的X, 這里用到了一個(gè)UIView的分類
- (void) distributeSpacingHorizontallyWith:(NSArray*)views;
這個(gè)分類直接用的里脊串的一篇文章中的代碼, 就不貼出代碼了, 簡單說一下原理, 如圖所示:

Paste_Image.png

實(shí)現(xiàn)原理就是在View中創(chuàng)建greenViews.count + 1個(gè)占位的View(藍(lán)色), 之后通過布局, 使占位View與要布局的View依次排開, 左右間距為0, 同時(shí)要約束所有的占位View寬度相等, 這樣看來, 這些占位View的寬度, 就是greenViews的間距, 也就可以實(shí)現(xiàn)等間距布局了.

至此, 我所知道的三種等間距布局方式就說完了, 具體代碼見

github地址:https://github.com/CoderLXWang/HowToUseMasonry

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 相信iOS開發(fā)人員, 沒人不知道m(xù)asonry是干什么的, 所以就不粘貼什么 "Masonry是一個(gè)輕量級(jí)的布局框...
    CoderLXWang閱讀 4,793評(píng)論 2 12
  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 178,671評(píng)論 25 709
  • 問答題47 /72 常見瀏覽器兼容性問題與解決方案? 參考答案 (1)瀏覽器兼容問題一:不同瀏覽器的標(biāo)簽?zāi)J(rèn)的外補(bǔ)...
    _Yfling閱讀 14,084評(píng)論 1 92
  • 發(fā)現(xiàn) 關(guān)注 消息 iOS 第三方庫、插件、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關(guān)注 2017.06.26 09:4...
    肇東周閱讀 14,994評(píng)論 4 61
  • 試讀:馮秋平笑的越發(fā)開心了,她對(duì)著沙發(fā)上的顧建波笑說,“老頭子,看吧,還是兒媳婦兒知道疼人!” 老爺子笑瞇瞇地附和...
    ALa工作室閱讀 1,857評(píng)論 0 0

友情鏈接更多精彩內(nèi)容