• iOS masonry九宫格 单行 多行布局


    Masonry是个好东西,在当前尺寸各异的iOS开发适配中发挥着至关重要的作用,由于项目中Masonry布局用的比较多,对于UI布局也有了一些自己的理解,经常会有人问道Masonry布局九宫格要怎么布局呢,单行、多行要怎么做到自动布局呢,之前用frame布局九宫格需要2层for循环,各种判断才可以完成一套九宫格布局,那使用Masonry是不是也这么麻烦呢,答案是否定的!下面把Masonry布局单行,多行的代码贴出来,注释的很详细,有需要的同学可以参考参考,可能对于Masonry的使用会有不一样的理解。
    图片

    代码

    //
    //  ViewController.m
    //  SudokuLayout
    //
    //  Created by Tiny on 2017/12/29.
    //  Copyright © 2017年 hxq. All rights reserved.
    //
    
    #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这个方法中
        //九宫格布局单行
        [self layoutOneLine];
        
        
        //九宫格布局多行 其实跟单行布局差不多,唯一要注意的是要判断换行的问题  为了体现差异,把两种单独写 代码确实有大量重复的
        //多行布局是支持单行的
        [self layoutMultiLine];
        
        
        //分析了代码可以看出来 多行布局和单行布局其实没有什么特殊的地方
        //区别点 1.确定什么时候换行
        //      2.确定距离布局区域顶部的距离多少
        //当前在真是开发环境中还会存在各种差异,但是只要理解了布局思路,相信不管怎么样布局都会游刃有余
        
    }
    
    
    -(void)layoutOneLine{
        //单行布局 不需要考虑换行的问题
        
        CGFloat marginX = 10;  //按钮距离左边和右边的距离
        CGFloat marginY = 10;  //按钮距离布局顶部的距离
        CGFloat toTop = 50;  //布局区域距离顶部的距离
        CGFloat gap = 10;    //按钮与按钮之间的距离
        NSInteger col = 5;    //这里只布局5列
        NSInteger count = 5;  //这里先设置布局5个按钮
        
        CGFloat viewWidth = self.view.bounds.size.width;  //视图的宽度
        CGFloat viewHeight = self.view.bounds.size.height;  //视图的高度
        
        CGFloat itemWidth = (viewWidth - marginX *2 - (col - 1)*gap)/col*1.0f;  //根据列数 和 按钮之间的间距 这些参数基本可以确定要平铺的按钮的宽度
        CGFloat height = itemWidth;   //按钮的高度可以根据情况设定 这里设置为相等
        
        UIButton *last = nil;   //上一个按钮
        //准备工作完毕 既可以开始布局了
        for (int i = 0 ; i < count; i++) {
            UIButton *item = [self buttonCreat];
            [item setTitle:@(i).stringValue forState:UIControlStateNormal];
            [self.view addSubview:item];
            
            //布局
            [item mas_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{
        //多行布局 要考虑换行的问题
        
        CGFloat marginX = 10;  //按钮距离左边和右边的距离
        CGFloat marginY = 1;  //距离上下边缘距离
        CGFloat toTop = 200;  //按钮距离顶部的距离
        CGFloat gapX = 10;    //左右按钮之间的距离
        CGFloat gapY = 10;    //上下按钮之间的距离
        NSInteger col = 5;    //这里只布局5列
        NSInteger count = 13;  //这里先设置布局任意个按钮
        
        CGFloat viewWidth = self.view.bounds.size.width;  //视图的宽度
        CGFloat viewHeight = self.view.bounds.size.height;  //视图的高度
        
        CGFloat itemWidth = (viewWidth - marginX *2 - (col - 1)*gapX)/col*1.0f;  //根据列数 和 按钮之间的间距 这些参数基本可以确定要平铺的按钮的宽度
        CGFloat itemHeight = itemWidth;   //按钮的高度可以根据情况设定 这里设置为相等
        
        UIButton *last = nil;   //上一个按钮
        //准备工作完毕 既可以开始布局了
        for (int i = 0 ; i < count; i++) {
            UIButton *item = [self buttonCreat];
            [item setTitle:@(i).stringValue forState:UIControlStateNormal];
            [self.view addSubview:item];
            
            //布局
            [item mas_makeConstraints:^(MASConstraintMaker *make) {
                
                //宽高是固定的,前面已经算好了
                make.width.mas_equalTo(itemWidth);
                make.height.mas_equalTo(itemHeight);
                
                //topTop距离顶部的距离,单行不用考虑太多,多行,还需要计算距离顶部的距离
                //计算距离顶部的距离 --- 根据换行
                CGFloat top = 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 = [[UIButton alloc] 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];
        [item setTitleColor:[UIColor redColor] forState:UIControlStateNormal];
        return item;
    }
    
    
    @end
    

    如上,代码中的注释已经很详细了,相信看到这里的同学都已经明白了布局原理,这里强调下最后总结的几句话:

    分析了代码可以看出来 多行布局和单行布局其实没有什么特殊的地方 区别点
    1.确定什么时候换行
    2.确定距离布局区域顶部的距离多少
    当然在真实开发环境中还会存在各种差异,但是只要理解了布局思路,相信不管怎么样布局都会游刃有余

    由于代码只有一个文件,也已经全部贴出来了。这里就不提供demo了(-_-)

    版权归tinych,qqcc1388所有,转载请标注转载来源:http://www.cnblogs.com/qqcc1388/p/8143836.html

  • 相关阅读:
    范仁义css3课程---33、背景3( background-attachment )
    范仁义css3课程---34、背景4( 背景简写属性 )
    范仁义css3课程---32、背景2( background-position)
    范仁义css3课程---31、背景1( background-image)
    关于Android Canvas.drawText方法中的坐标参数的正确解释
    android中画文字的换行 办法(对于遇到canvas.drawText(String s )无法实现换行问题的解决)
    Android中自定义属性(attrs.xml,TypedArray的使用)
    推荐
    intent的startActivityForResult()方法
    Android利用Gson解析嵌套多层的Json
  • 原文地址:https://www.cnblogs.com/qqcc1388/p/8143836.html
Copyright © 2020-2023  润新知