美文网首页iOS开发(OC)
Masonry布局ScrollerView以及一些复杂的布局

Masonry布局ScrollerView以及一些复杂的布局

作者: 兰州啊兰州 | 来源:发表于2017-05-11 13:04 被阅读99次

    这是我的第一篇简书,随便写写,记录下Masonry布局的一些常用技巧!

    这里要是有不了解Masonry的同学,请自行百度!

    1.Masonry布局scrollerView

    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.搜索记录,标签等布局

    标签视图

    像这种大小不一的标签视图,现在的应用上面还是比较常见的,想搜索记录,推荐,类别分类的功能模块上都有可能用到。这里的难点就在对标签长度的以及换行的计算;算了我直接上代码(为什么我看人家的代码五颜六色的,我的却是黑白的❓蛋疼的很) 我直接上代码截图了!

    代码片段1

    这里我先是对标签视图的组头标签也就是图片“标签视图”的“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)"

    这里完成对组头标签的布局。

    代码片段2

    这里是在创建组头标签的循环里嵌套循环创建子视图和布局的代码,也是重点。 我这里先是标记了一个长度currentWidth,这个长度代表的是当前创建的这个子标签的起始长度,可以理解为子标签的 origin.x,用这个currentWidth将子标签的width加起来对换行进行判断。

    "CGFloat BtnW = [btn.titleLabel.text sizeWithFont:btn.font].width" 这里可以算出文字所占的长度,即为标签长度。在布局中判断是否超出父视图长度,随后添加约束。

    在最后别忘了将lastBtn更新为当前的标签按钮,以及更新currentWidth。

    代码片段3

    最后添加黑色确定按钮的约束,还是那句话"做到父视图的上下左右的约束完整"。

    3张代码片段图片拼起来就是完整的布局代码。

    第一次写简书,不足请谅解!(原谅我,我会努力的)

    Masonry还有很多NB的地方,我也是在学习中,上面的代码要是不足之处请指出,若有不理解的地方请联系我:

    163邮箱

    相关文章

      网友评论

      • 舒马赫:Masory写的很棒,但是不喜欢纯代码写界面,太慢了,另外由于autolayout先天原因布局速度是比较慢的,会影响帧率。推荐使用xml的布局库FlexLib,采用前端布局标准flexbox(不使用autolayout),支持热刷新,自动计算高度等。可以到这里了解详细信息:

        https://github.com/zhenglibao/FlexLib
      • 兰州啊兰州:13048914897@163.com 这个是作者邮箱

      本文标题:Masonry布局ScrollerView以及一些复杂的布局

      本文链接:https://www.haomeiwen.com/subject/vvzntxtx.html