以下將從幾個方面說一下如何使用Masonry
- 怎樣添加約束才能滿足一個View, 及masonry的基本使用
- 如何使用masonry等間隙排布幾個View
- 更新約束動畫
- ScrolView如何布局
- tableViewCell高度動態(tài)變化
2. 如何使用masonry等間隙排布幾個View
先直接上圖, 最終要實現(xiàn)這樣一個布局
這里一共三部分, 最上面黃色的中間藍色的都是用了masonry提供的方法, 適用于等大小的View等間距布局, 最下面的綠色View是自己自己封裝的分類, 適用于不等大VIew的等間距布局, 來自于這邊經(jīng)典的文章Masonry介紹與使用實踐:快速上手Autolayout
接下來分別說一下這三部分
第一部分, 直接上代碼
//在紅色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){}
完成布局.
第二部分, 代碼如下:
//在紅色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)布局.
同樣這個方法完成了水平方向的布局, 還需要完成豎直方向的布局.
第三部分, 代碼如下:
//在紅色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;
這個分類直接用的里脊串的一篇文章中的代碼, 就不貼出代碼了, 簡單說一下原理, 如圖所示:
實現(xiàn)原理就是在View中創(chuàng)建greenViews.count + 1
個占位的View(藍色), 之后通過布局, 使占位View與要布局的View依次排開, 左右間距為0, 同時要約束所有的占位View寬度相等, 這樣看來, 這些占位View的寬度, 就是greenViews的間距, 也就可以實現(xiàn)等間距布局了.
至此, 我所知道的三種等間距布局方式就說完了, 具體代碼見