这是我的第一篇简书,随便写写,记录下Masonry布局的一些常用技巧!
这里要是有不了解Masonry的同学,请自行百度!
1.Masonry布局scrollerView
之间在第一次接触Masonry布局scrollerView的时候依然会想着先赋值scrollerView.contentSize,但是Masonry布局的视图你是无法第一时间拿到frame,需要在合适的时候[self layoutIfNeeded]视图才会完成布局得到frame。并且还要根据数据大小来设置Size的height或是Width。现在回头想想着实有些愚蠢。正确的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张代码片段图片拼起来就是完整的布局代码。
第一次写简书,不足请谅解!(原谅我,我会努力的)
Masonry还有很多NB的地方,我也是在学习中,上面的代码要是不足之处请指出,若有不理解的地方请联系我: