這是我的第一篇簡書,隨便寫寫,記錄下Masonry布局的一些常用技巧!
這里要是有不了解Masonry的同學,請自行百度!
1.Masonry布局scrollerView
之間在第一次接觸Masonry布局scrollerView的時候依然會想著先賦值scrollerView.contentSize,但是Masonry布局的視圖你是無法第一時間拿到frame,需要在合適的時候[self layoutIfNeeded]視圖才會完成布局得到frame。并且還要根據數據大小來設置Size的height或是Width?,F在回頭想想著實有些愚蠢。正確的Maonry布局scrollerView可以不用設置contentSize屬性,是需要在scrollerView上在覆蓋一層contentView,并對contentView進行合理布局。
@property? (nonatomic,strong)? ? ? UIScrollView? ? *scroller;
@property? (nonatomic,strong)? ? ? UIView ? ? ? ? ? ? ? *scrollerContentView;
下面是scrillerContentView的Masonry布局代碼
self.scrollerContentView = [[UIView alloc]init];
[self.scroller addSubview:self.scrollerContentView];
mas_makeConstraints:^(MASConstraintMaker *make) {
make.edges.mas_equalTo(weakSelf.scroller);
make.height.mas_equalTo(weakSelf.scroller);
}];
這里需要注意了,若你的scrollerView是支持橫向滑動的,這么寫 “make.height.mas_equalTo(weakSelf.scroller)" 沒錯,此時scrollerView.contentSize的高是固定的。倘若你的scrollerView支持豎直方向滑動,則應該對width添加約束,此時長度是固定的,應該寫成“make.width.mas_equalTo(weakSelf.scroller)"。這里算是完成了對scrollerContentView的布局。
接下來是scrollerView上的子視圖的布局。
所有的子視圖都添加到scrollerContentView上面,然后添加約束,這都不難。關鍵的是對最后的一個子視圖的約束。做到子視圖對scrollerContentView的上下左右都有約束,這樣才能確定scrollerContentView的位置和大小。
[self.scrollerContentView addSubview:bgView];
[bgView mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.bottom.mas_equalTo(weakSelf.scrollerContentView);
weakSelf.lastBgView ? (make.left.mas_equalTo(weakSelf.lastBgView.mas_right).offset(10 * LAYOUT_WIDTH)) : (make.left.mas_equalTo(weakSelf.scrollerContentView));
make.width.mas_equalTo(180 * LAYOUT_WIDTH);
i == dataArr.count - 1 && i > 0 ? (make.right.mas_equalTo(weakSelf.scrollerContentView)) : nil;
}];
上面的背景是我循環創建子視圖bgView添加到scrollerContentView上面,然后Masonry添加約束??梢钥吹竭@行代碼:
“i == dataArr.count - 1 && i > 0 ? (make.right.mas_equalTo(weakSelf.scrollerContentView)) : nil;”
在布局最后一個子視圖的時候添加了子視圖的右邊對scrollerContentView的右邊的約束。(這里我是橫向滑動的scrollerView,若是豎直方向滑動的scroller應該對子視圖的top或是bottom對scrollerContentView進行約束),這樣算是完成了對scrollerView的Masonry布局。
2.兩個非對稱的視圖居中
需求就是這樣:廚師帽子的圖標和“名廚推薦”的標簽居中。
其實布局很簡單,創建一個容器View,圖標和標簽都添加到容器view上面。容器View對父視圖的布局是center.x與父視圖無偏差(這個是關鍵),其他約束能確定容器View位置即可。容器View的子視圖的布局思想和布局scrollerContentView的思想一樣,做到對容器的上下左右都有布局,這樣就能確定容器View的大小。
下面的代碼:
UIView *bgView = [[UIView alloc]init]; ? ? ? ? //這個是容器View
[titlebgView addSubview:bgView];
self.titleImageView = [[UIImageView alloc]init]; ? ? ?//子視圖圖標
[bgView addSubview:self.titleImageView];
[self.titleImageView mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.top.bottom.mas_equalTo(bgView);
make.height.width.mas_equalTo(25 * LAYOUT_WIDTH);
}];
self.titleLabel = [[UILabel alloc]init]; ? ? ?//子視圖標簽
self.titleLabel.textColor = [UIColor blackColor];
self.titleLabel.font = [UIFont systemFontOfSize:15];
[bgView addSubview:self.titleLabel];
[self.titleLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.mas_equalTo(weakSelf.titleImageView.mas_right).offset(5 * LAYOUT_WIDTH);
make.centerY.mas_equalTo(weakSelf.titleImageView);
make.right.mas_equalTo(bgView);
}];
[bgView mas_makeConstraints:^(MASConstraintMaker *make) {
make.center.mas_equalTo(titlebgView);
}];
3.搜索記錄,標簽等布局
像這種大小不一的標簽視圖,現在的應用上面還是比較常見的,想搜索記錄,推薦,類別分類的功能模塊上都有可能用到。這里的難點就在對標簽長度的以及換行的計算;算了我直接上代碼(為什么我看人家的代碼五顏六色的,我的卻是黑白的?蛋疼的很) 我直接上代碼截圖了!
這里我先是對標簽視圖的組頭標簽也就是圖片“標簽視圖”的“title-0"和”title-1"的創建和約束。這里我定義了一個UIButton *lastBtn 來記錄title下面當前所創建的最后一個子標簽。
"lastBtn ? (make.top.mas_equalTo(lastBtn.mas_bottom).offset(10 * LAYOUT_HEIGHT)) : (make.top.mas_equalTo(weakSelf).offset(5 * LAYOUT_HEIGHT))"
可以看到 lastBtn為nil的話,說明title標簽為第一個,添加約束"make.top.mas_equalTo(weakSelf).offset(5 * LAYOUT_HEIGHT)" ;
lastBtn被賦值的話說明已經有子標簽創建,并且為當前的最后一個,故添加約束"make.top.mas_equalTo(lastBtn.mas_bottom).offset(10 * LAYOUT_HEIGHT)"
這里完成對組頭標簽的布局。
這里是在創建組頭標簽的循環里嵌套循環創建子視圖和布局的代碼,也是重點。 我這里先是標記了一個長度currentWidth,這個長度代表的是當前創建的這個子標簽的起始長度,可以理解為子標簽的 origin.x,用這個currentWidth將子標簽的width加起來對換行進行判斷。
"CGFloat BtnW = [btn.titleLabel.text sizeWithFont:btn.font].width" 這里可以算出文字所占的長度,即為標簽長度。在布局中判斷是否超出父視圖長度,隨后添加約束。
在最后別忘了將lastBtn更新為當前的標簽按鈕,以及更新currentWidth。
最后添加黑色確定按鈕的約束,還是那句話"做到父視圖的上下左右的約束完整"。
3張代碼片段圖片拼起來就是完整的布局代碼。
第一次寫簡書,不足請諒解?。ㄔ徫遥視Φ模?/p>
Masonry還有很多NB的地方,我也是在學習中,上面的代碼要是不足之處請指出,若有不理解的地方請聯系我: