Masonry是个好东西,在当前尺寸各异的iOS开发适配中发挥着至关重要的作用,由于项目中Masonry布局用的比较多,对于UI布局也有了一些自己的理解,经常会有人问道Masonry布局九宫格要怎么布局呢,单行、多行要怎么做到自动布局呢,之前用frame布局九宫格需要2层for循环,各种判断才可以完成一套九宫格布局,那使用Masonry是不是也这么麻烦呢,答案是否定的!下面把Masonry布局单行,多行的代码贴出来,注释的很详细,有需要的同学可以参考参考,可能对于Masonry的使用会有不一样的理解。
图片
代码
#import "ViewController.h"
#import "Masonry.h"
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
//如果需要考虑横竖屏可以将布局代码写在LayoutSubViews这个方法中
//九宫格布局单行
[selflayoutOneLine];
//九宫格布局多行 其实跟单行布局差不多,唯一要注意的是要判断换行的问题 为了体现差异,把两种单独写 代码确实有大量重复的
//多行布局是支持单行的
[selflayoutMultiLine];
//分析了代码可以看出来 多行布局和单行布局其实没有什么特殊的地方
//区别点 1.确定什么时候换行
// 2.确定距离布局区域顶部的距离多少
//当前在真是开发环境中还会存在各种差异,但是只要理解了布局思路,相信不管怎么样布局都会游刃有余
}
-(void)layoutOneLine{
//单行布局 不需要考虑换行的问题
CGFloatmarginX =10; //按钮距离左边和右边的距离
CGFloatmarginY =10; //按钮距离布局顶部的距离
CGFloattoTop =50; //布局区域距离顶部的距离
CGFloatgap =10; //按钮与按钮之间的距离
NSIntegercol =5; //这里只布局5列
NSIntegercount =5; //这里先设置布局5个按钮
CGFloat viewWidth = self.view.bounds.size.width; //视图的宽度
CGFloat viewHeight = self.view.bounds.size.height; //视图的高度
CGFloatitemWidth = (viewWidth - marginX *2- (col -1)*gap)/col*1.0f; //根据列数 和 按钮之间的间距 这些参数基本可以确定要平铺的按钮的宽度
CGFloatheight = itemWidth; //按钮的高度可以根据情况设定 这里设置为相等
UIButton*last =nil; //上一个按钮
//准备工作完毕 既可以开始布局了
for(inti =0; i < count; i++) {
UIButton*item = [selfbuttonCreat];
[itemsetTitle:@(i).stringValue forState:UIControlStateNormal];
[self.viewaddSubview:item];
//布局
[itemmas_makeConstraints:^(MASConstraintMaker*make) {
//宽高是固定的,前面已经算好了
make.width.mas_equalTo(itemWidth);
make.height.mas_equalTo(height);
//topTop距离顶部的距离,单行不用考虑太多,多行,还需要计算距离顶部的距离
make.top.mas_offset(toTop+marginY);
if(!last) { //last为nil 说明是第一个按钮
make.left.mas_offset(marginX);
}else{
//第二个或者后面的按钮 距离前一个按钮右边的距离都是gap个单位
make.left.mas_equalTo(last.mas_right).mas_offset(gap);
}
}];
last = item;
}
}
-(void)layoutMultiLine{
//多行布局 要考虑换行的问题
CGFloatmarginX =10; //按钮距离左边和右边的距离
CGFloatmarginY =1; //距离上下边缘距离
CGFloattoTop =200; //按钮距离顶部的距离
CGFloatgapX =10; //左右按钮之间的距离
CGFloatgapY =10; //上下按钮之间的距离
NSIntegercol =5; //这里只布局5列
NSIntegercount =13; //这里先设置布局任意个按钮
CGFloat viewWidth = self.view.bounds.size.width; //视图的宽度
CGFloat viewHeight = self.view.bounds.size.height; //视图的高度
CGFloatitemWidth = (viewWidth - marginX *2- (col -1)*gapX)/col*1.0f; //根据列数 和 按钮之间的间距 这些参数基本可以确定要平铺的按钮的宽度
CGFloatitemHeight = itemWidth; //按钮的高度可以根据情况设定 这里设置为相等
UIButton*last =nil; //上一个按钮
//准备工作完毕 既可以开始布局了
for(inti =0; i < count; i++) {
UIButton*item = [selfbuttonCreat];
[itemsetTitle:@(i).stringValue forState:UIControlStateNormal];
[self.viewaddSubview:item];
//布局
[itemmas_makeConstraints:^(MASConstraintMaker*make) {
//宽高是固定的,前面已经算好了
make.width.mas_equalTo(itemWidth);
make.height.mas_equalTo(itemHeight);
//topTop距离顶部的距离,单行不用考虑太多,多行,还需要计算距离顶部的距离
//计算距离顶部的距离 --- 根据换行
CGFloattop = toTop + marginY + (i/col)*(itemHeight+gapY);
make.top.mas_offset(top);
if (!last || (i%col) == 0) { //last为nil 或者(i%col) == 0 说明换行了 每行的第一个确定它距离左边边缘的距离
make.left.mas_offset(marginX);
}else{
//第二个或者后面的按钮 距离前一个按钮右边的距离都是gap个单位
make.left.mas_equalTo(last.mas_right).mas_offset(gapX);
}
}];
last = item;
}
}
#pragma mark - Private
-(UIButton*)buttonCreat{
UIButton*item = [[UIButtonalloc]init];
item.backgroundColor = [UIColor colorWithRed:arc4random_uniform(256)/255.0 green:arc4random_uniform(256)/255.0 blue:arc4random_uniform(256)/255.0 alpha:1.0f];
item.titleLabel.font = [UIFont systemFontOfSize:16];
[itemsetTitleColor:[UIColor redColor] forState:UIControlStateNormal];
returnitem;
}
@end
如上,代码中的注释已经很详细了,相信看到这里的同学都已经明白了布局原理,这里强调下最后总结的几句话:
分析了代码可以看出来 多行布局和单行布局其实没有什么特殊的地方
区别点 1.确定什么时候换行
2.确定距离布局区域顶部的距离多少
当前在真是开发环境中还会存在各种差异,但是只要理解了布局思路,相信不管怎么样布局都会游刃有余