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

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

以下將從幾個方面說一下如何使用Masonry

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

2. 如何使用masonry等間隙排布幾個View

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

Paste_Image.png

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

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

第一部分, 直接上代碼

Paste_Image.png
    //在紅色View里面放三個正方形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提供了這樣一個方法:

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

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

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

第二部分, 代碼如下:

Paste_Image.png
    //在紅色View里面放三個正方形藍色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提供的另一個方法, 和上一個方法基本完全一樣

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

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

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

第三部分, 代碼如下:

Paste_Image.png
    //在紅色View里面放三個大小不一樣的綠色正方形, 間隙等大, 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) , 完成了底部位置, 寬, 高的布局, 還缺少水平方向的位置, 即還要確定每個view的X, 這里用到了一個UIView的分類
- (void) distributeSpacingHorizontallyWith:(NSArray*)views;
這個分類直接用的里脊串的一篇文章中的代碼, 就不貼出代碼了, 簡單說一下原理, 如圖所示:

Paste_Image.png

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

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

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

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

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

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