zoukankan      html  css  js  c++  java
  • 如何使用masonry设计复合型cell[转]

    前言

    其实早在@sunnyxx同学发布UIView-FDCollapsibleConstraints的时候 我就说要写一下怎么用代码来稍微麻烦的实现复用的问题 但是一直各种没时间(主要是我的办法太复杂 - -) 正好看到@叶孤城同学也说了一下他的解决办法 所以我来说一下我是如何解决这个问题的

    分析

    我们以叶孤城同学的例子来简单分析一下 假设view是这样的(为了方便 将所有的间隙设定为20)

    正常的布局是这样的

    blob.png

    布局代码如下:

    interface ComplexCell()
    @property (nonatomic, strong) UIView *vB; //view blue    height:30
    @property (nonatomic, strong) UIView *vY; //view yellow  height:30
    @property (nonatomic, strong) UIView *vR; //view red     height:30
    @property (nonatomic, strong) UIView *vG; //view green   height:100
    @end
    - (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
         
        self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
         
         
         
        if ( self ) {
             
            CGFloat spacing = 20.0f;
             
            self.vB = [UIView new];
            [self.contentView addSubview:self.vB];
            [self.vB mas_makeConstraints:^(MASConstraintMaker *make) {
                make.left.top.equalTo(self.contentView).insets(UIEdgeInsetsMake(spacing,spacing,0,0));
                make.width.equalTo(@60);
                make.height.equalTo(@30).priorityLow();
                self.cB = make.height.equalTo(@0).priority(UILayoutPriorityRequired);
            }];
            self.vB.backgroundColor = [UIColor blueColor];
             
             
            self.vY = [UIView new];
            [self.contentView addSubview:self.vY];
            [self.vY mas_makeConstraints:^(MASConstraintMaker *make) {
                make.left.equalTo(self.vB.mas_right).offset(spacing);
                make.right.top.equalTo(self.contentView).insets(UIEdgeInsetsMake(spacing,0,0,spacing));
                make.height.equalTo(@30).priorityLow();
                self.cY = make.height.equalTo(@0).priority(UILayoutPriorityRequired);
            }];
            self.vY.backgroundColor = [UIColor yellowColor];
             
            self.vR = [UIView new];
            [self.contentView addSubview:self.vR];
            [self.vR mas_makeConstraints:^(MASConstraintMaker *make) {
                make.top.equalTo(self.vB.mas_bottom).offset(spacing);
                make.left.right.equalTo(self.contentView).insets(UIEdgeInsetsMake(0,spacing,0,spacing));
                make.height.equalTo(@30).priorityLow();
                self.cR = make.height.equalTo(@0).priority(UILayoutPriorityRequired);
            }];
            self.vR.backgroundColor = [UIColor redColor];
             
            self.vG = [UIView new];
            [self.contentView addSubview:self.vG];
            [self.vG mas_makeConstraints:^(MASConstraintMaker *make) {
                make.top.equalTo(self.vR.mas_bottom).offset(spacing);
                make.left.right.equalTo(self.contentView).insets(UIEdgeInsetsMake(0,spacing,0,spacing));
                make.height.equalTo(@100).priorityLow();
                self.cG = make.height.equalTo(@0).priority(UILayoutPriorityRequired);
            }];
            self.vG.backgroundColor = [UIColor greenColor];
             
        }
         
        return self;

    实际效果如图

    blob.png

    看上去还不错

    在Masonry中 针对单条的MASLayoutConstraint可以进行activedeactive操作 那么意味着可以动态的启用或者禁用某条预置的约束 所以我们只要预先设置一条高优先级的高度为0(或者宽度为0)的约束 然后在适当的时候激活它不就行了? 先尝试隐藏红色的view 隐藏后如下

    blob.png

    啊~哦~ 结果不正确 隐藏是隐藏了 但是间隙没有隐藏 导致缝变大了 这是因为我们仅仅隐藏了view 而没有隐藏view之间的间隔 那么应该如何处理这种情况呢?

    主流的做法是将这个view的所有约束值全设置成0 然后恢复的时候再还原 这种方法需要记录原值 但是在前言我说了 要用稍微麻烦的方法来解决这个问题 所以肯定不是这样做啦

    我采用的方法是group法 具体如下图

    blob.png

    其实在第一行还有一个groupview如图

    blob.png

    但是因为图显示出来不太好看(不会画图 T_T ) 所以我隐藏了 具体可以看代码细节

    每个(或者每组)可以隐藏的view 都对应有一个group view(group其实就是包含了view和spacing) 需要隐藏的时候 直接隐藏这个group 就可以达到既隐藏view又缩短间隙的目的

    代码较长 大家可以选择跳过 - -!

    @interface ComplexCell()
    @property (nonatomic, strong) MASConstraint *cF; //constraint first row
    @property (nonatomic, strong) MASConstraint *cB; //constraint blue
    @property (nonatomic, strong) MASConstraint *cY; //constraint yellow
    @property (nonatomic, strong) MASConstraint *cR; //constraint red
    @property (nonatomic, strong) MASConstraint *cG; //constraint green
    @property (nonatomic, strong) UIView *gF; //group first row
    @property (nonatomic, strong) UIView *gB; //group blue
    @property (nonatomic, strong) UIView *gY; //group yellow
    @property (nonatomic, strong) UIView *gR; //group red
    @property (nonatomic, strong) UIView *gG; //group green
    @property (nonatomic, strong) UIView *vB; //view blue    height:30
    @property (nonatomic, strong) UIView *vY; //view yellow  height:30
    @property (nonatomic, strong) UIView *vR; //view red     height:30
    @property (nonatomic, strong) UIView *vG; //view green   height:100
    @end
    @implementation ComplexCell
    - (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
         
        self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
         
         
        if ( self ) {
             
            CGFloat spacing = 20.0f;
             
             
            self.gF = [UIView new];
            [self.contentView addSubview:self.gF];
            [self.gF mas_makeConstraints:^(MASConstraintMaker *make) {
                make.left.top.right.equalTo(self.contentView);
                 
                self.cF = make.height.equalTo(@0).priority(UILayoutPriorityRequired);
                [self.cF deactivate];
            }];
            self.gF.clipsToBounds = YES;
             
            self.gB = [UIView new];
            [self.gF addSubview:self.gB];
            [self.gB mas_makeConstraints:^(MASConstraintMaker *make) {
                make.left.top.bottom.equalTo(self.gF);
                 
                self.cB = make.width.equalTo(@0).priority(UILayoutPriorityRequired);
                [self.cB deactivate];
            }];
            self.gB.clipsToBounds = YES;
             
            self.gY = [UIView new];
            [self.gF addSubview:self.gY];
            [self.gY mas_makeConstraints:^(MASConstraintMaker *make) {
                make.right.top.bottom.equalTo(self.gF);
                make.left.equalTo(self.gB.mas_right);
                 
                self.cY = make.width.equalTo(@0).priority(UILayoutPriorityRequired);
                [self.cY deactivate];
            }];
            self.gY.clipsToBounds = YES;
             
            self.gR = [UIView new];
            [self.contentView addSubview:self.gR];
            [self.gR mas_makeConstraints:^(MASConstraintMaker *make) {
                make.left.right.equalTo(self.contentView);
                make.top.equalTo(self.gF.mas_bottom);
                 
                self.cR = make.height.equalTo(@0).priority(UILayoutPriorityRequired);
                [self.cR deactivate];
            }];
            self.gR.clipsToBounds = YES;
             
            self.gG = [UIView new];
            [self.contentView addSubview:self.gG];
            [self.gG mas_makeConstraints:^(MASConstraintMaker *make) {
                make.left.right.equalTo(self.contentView);
                make.top.equalTo(self.gR.mas_bottom);
                 
                self.cG = make.height.equalTo(@0).priority(UILayoutPriorityRequired);
                [self.cG deactivate];
            }];
            self.gG.clipsToBounds = YES;
             
             
            self.vB = [UIView new];
            [self.gB addSubview:self.vB];
            [self.vB mas_makeConstraints:^(MASConstraintMaker *make) {
                make.edges.equalTo(self.gB).insets(UIEdgeInsetsMake(spacing, spacing, 0, 0)).priorityLow();
                make.height.equalTo(@30);
                make.width.equalTo(@60);
            }];
            self.vB.backgroundColor = [UIColor blueColor];
             
             
            self.vY = [UIView new];
            [self.gY addSubview:self.vY];
            [self.vY mas_makeConstraints:^(MASConstraintMaker *make) {
                make.edges.equalTo(self.gY).insets(UIEdgeInsetsMake(spacing, spacing, 0, spacing)).priorityLow();
                make.height.equalTo(@30);
            }];
            self.vY.backgroundColor = [UIColor yellowColor];
             
            self.vR = [UIView new];
            [self.gR addSubview:self.vR];
            [self.vR mas_makeConstraints:^(MASConstraintMaker *make) {
                make.edges.equalTo(self.gR).insets(UIEdgeInsetsMake(spacing, spacing, 0, spacing)).priorityLow();
                make.height.equalTo(@30);
            }];
            self.vR.backgroundColor = [UIColor redColor];
             
            self.vG = [UIView new];
            [self.gG addSubview:self.vG];
            [self.vG mas_makeConstraints:^(MASConstraintMaker *make) {
                make.edges.equalTo(self.gG).insets(UIEdgeInsetsMake(spacing, spacing, 0, spacing)).priorityLow();
                make.height.equalTo(@100);
            }];
            self.vG.backgroundColor = [UIColor greenColor];
             
        }
         
        return self;
    }

    然后 为每种不同的布局定义一个枚举(为了举例我随便定义的 0和1代表这个view是否被显示)

    typedef NS_ENUM(NSUInteger, ComplexType) {
        ComplexType1111,
        ComplexType1110,
        ComplexType0111,
        ComplexType0011,
        ComplexType0010,
        ComplexType1101
    };
    @interface ComplexCell : UITableViewCell
    @property (nonatomic, assign) ComplexType type;
    @end
    - (void)setType:(ComplexType)type {
         
        [self.cF deactivate];
        [self.cB deactivate];
        [self.cY deactivate];
        [self.cR deactivate];
        [self.cG deactivate];
         
        switch (type) {
            case ComplexType1111:
            {
                break;
            }
            case ComplexType0111:
            {
                [self.cB activate];
                break;
            }
            case ComplexType0011:
            {
                [self.cF activate];
                break;
            }
            case ComplexType1110:
            {
                [self.cG activate];
                break;
            }
            case ComplexType1101:
            {
                [self.cR activate];
                break;
            }
            case ComplexType0010:
            {
                [self.cF activate];
                [self.cG activate];
                break;
            }
                 
            default:
                break;
        }
    }

    这样 在tableview的datasource中我们只要这样做就可以了

    - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
        return 1;
    }
    - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
        return 6;
    }
    - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
        return [ComplexCell getHeightByType:indexPath.row%6];
    }
    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
         
        ComplexCell* cell = [tableView dequeueReusableCellWithIdentifier:@"cell"];
        cell.type = indexPath.row%6;
         
        return cell;
    }

    看看效果 是不是很不错

    blob.png

    blob.png

    blob.png

    blob.png

    blob.png

    blob.png

    小结

    文中的demo可以在这里找到 要注意的地方是约束的priority的设置 另外 这种方式也支持不定长内容的Autolayout

    可能很多人看了觉得我在瞎折腾 明明一个挺简单实现的东西 被我一弄 弄得又长又臭 其实不然 像我这种方法虽然麻烦了点(文章开头就指出了) 但是面对稍微复杂点的需求 却是更得心应手(其实有点类似DIV+CSS的感觉有木有?)

    使用group的方式 面对同时在横向和纵向都有隐藏要求的时候 会方便很多

    比如文中举的例子 第一行有时会隐藏蓝色的按钮 有时整个一行都会不显示 这样的话 当我想隐藏按钮时 只要激活按钮的约束 想隐藏整行时 只要激活整行的那条约束就行了

    from:http://adad184.com/2015/06/08/complex-cell-with-masonry/

  • 相关阅读:
    c# 委托
    datagrid加下拉列表dropdownlist
    MySQL存储过程的基本函数(三)
    MySQL存储过程详解 mysql 存储过程(二)
    MySQL存储过程(一)
    SFTP 文件上传下载引用代码
    JAVA SFTP文件上传、下载及批量下载
    java中遍历MAP的几种方法
    POSTGRESQL 导入导出
    db2move 数据导出整理
  • 原文地址:https://www.cnblogs.com/sunshine-anycall/p/4812790.html
Copyright © 2011-2022 走看看