TAG

RSS订阅

收藏本站

设为首页

当前位置:主页 > 移动开发 > IOS开发 >

AutoLayout 使用Masonry UITableViewCell的自适应高度

发布时间:2016-03-16 17:28 类别:IOS开发



AutoLayout  使用Masonry UITableViewCell的自适应高度

第一步、Base TableViewController 封装tableView的 数据源方法、代理方法。这里只给出cell height的代理函数部分:

  
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {

    //不使用高度自适应的cell,返回其设置的默认高度
    if (![[self cellClass] isDynamic]) {
        return [self cellDefaultHeight];
    }

    __weak typeof(self) weakSelf = self;

    //每个Cell类设置的,默认Size
    CGSize defaultSize = [[self cellClass] defaultCellSize];

    //计算后自适应的 size
    CGSize cellSize = [[self cellClass] sizeForCellWithDefaultSize:defaultSize
                                                    setupCellBlock:^id(id<ZSYAutoLayoutCellProtocol> cellToSetup)
    {
        NSArray *dataList = [weakSelf dataSource];
        id obj = nil;

        //取出当前cell,要显示的实体对象
        if ([self sectionCount] == 1) {
            //dataSource是一维数组
            obj = dataList[[indexPath row]];
        } else {
            //dataSource是一维数组
            NSArray *sectionArray = dataList[indexPath.section];
            obj = sectionArray[indexPath.row];
        }

        //让cell根据实体对象【决定哪些view显示数据,显示什么数据,让cell针对当前实体对象的属性,初始化cell.contentView.subViews 】
        [cellToSetup setupDataItem:obj];

        //返回一个设置完了显示数据、设置好内部subViews约束的cell对象
        return cellToSetup;

    }];

    return cellSize.height;

}


第二步、BaseCell封装计算设置好约束、设置好显示数据cell对象高度的方法
+ (CGSize)sizeForCellWithDefaultSize:(CGSize)defaultSize setupCellBlock:(setupCellBlock)block {

    __block ZSYBaseCell *cell = nil;

    //使用一个静态变量数组cellArray保存所有需要适配高度的Cell类的一个唯一的对象,方便后续计算cell设置好数据后的高度    

    //先从静态数组查找,是否存在当前需要适配高度的cell类型的一个对象
    [cellArray enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
        if ([obj isKindOfClass:[[self class] class]]) {
            cell = obj;
            *stop = YES;
        }
    }];

    //如果没找到,就创建一个新的cell对象,并保存到静态数组,方便后续使用
    if (!cell) {
        cell = [[[self class] alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"XZHAutoLayoutCellIdentifier"];
        cell.frame = CGRectMake(0, 0, defaultSize.width, defaultSize.height);
        [cellArray addObject:cell];
    }

    //针对一些cell不同数据,cell内部的subViews发生增加、减少类似的情况。通过子类cell重写这个方法,完成在不同的实体数据时,增加删除subviews
    [cell resetSubviews];

    //获取到设置了属性值的cell对象【会执行一次cell的setupData方法】
    cell = block((id<ZSYAutoLayoutCellProtocol>) cell);

    //最好写上
    [cell setNeedsLayout];
    [cell layoutIfNeeded];

    //使用系统函数,计算得到cell的高度
    //注意: 【必须在cell对象调用setupData: 时,对内部subviews正确设置约束,此时才能正确计算出高度】
    CGSize size = [cell.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize];

    //加上一个1.0f,cell底部的分割线
    size.height += 1.0f;

    //返回高度
    return size;
}


第三步、编写继承自BaseCell的HomePageCell完成高度自适应



效果图

技术分享 技术分享技术分享 cell结构: 一个imageview,一个label, 多张不固定的图片、每个图片可以有一个优惠的圆形label
// 第一步、cell在init初始化时,创建公共的subviews添加到contentView,并设置约束

- (id)initWithStyle:(UITableViewCellStyle)style
    reuseIdentifier:(NSString *)reuseIdentifier
{
    self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
    if (self) {
        [self initSubviews];
    }
    return self;
}

- (void)initSubviews {
    _subViews = [NSMutableArray array];

    self.backgroundColor = [UIColor whiteColor];
    self.accessoryType = UITableViewCellAccessoryNone;
    self.accessoryView = nil;
    self.selectionStyle = UITableViewCellSelectionStyleNone;

    _titleLeftImageView = [[UIImageView alloc] init];
    _titleLeftImageView.image = [UIImage imageNamed:@"icon_title"];
    _titleLeftImageView.translatesAutoresizingMaskIntoConstraints = NO;
    _titleLeftImageView.contentMode = UIViewContentModeScaleAspectFill;

    _titleLabel = [[UILabel alloc] init];
    _titleLabel.textAlignment = NSTextAlignmentLeft;
    _titleLabel.numberOfLines = 0;
    _titleLabel.lineBreakMode = NSLineBreakByWordWrapping;
    _titleLabel.translatesAutoresizingMaskIntoConstraints = NO;
    _titleLabel.font = [UIFont fontWithName:@"HelveticaNeue" size:15];
    _titleLabel.textColor = [UIColor hex:@"#514647"];

    [self.contentView addSubview:_titleLeftImageView];
    [self.contentView addSubview:_titleLabel];

    @weakify(self);
    [self.contentView mas_makeConstraints:^(MASConstraintMaker *make) {
        @strongify(self);
        make.edges.equalTo(self);
        make.width.equalTo(self);
    }];

    //一定要给自动换行计算高度的label,设置最大宽度
    [self preferMaxWidthLabels];

//    [self setNeedsUpdateConstraints];
//    [self updateConstraintsIfNeeded];
}

// 第二步、 给Label设置最大宽度
- (void)preferMaxWidthLabels {

    _metricDict = @{
                      @"sideBuffer1" : @12,
                      @"sideBuffer2" : @10,
                      @"vertical_top_Buffer" : @12,
                      @"vertical_middle_Buffer" : @16,
                      @"vertical_bottom_Buffer" : @12.5,
                      @"labelImageSizeWith" : @(_titleLeftImageView.image.size.width),
                      @"labelImageSizeHeight" : @(_titleLeftImageView.image.size.height),
                      @"contentImageSizeHeight" : @181
                      };

//    [self.titleLabel setContentCompressionResistancePriority:UILayoutPriorityRequired forAxis:UILayoutConstraintAxisVertical];
//    [self.titleLabel setContentCompressionResistancePriority:UILayoutPriorityDefaultLow forAxis:UILayoutConstraintAxisHorizontal];
    

    CGSize defaultSize = [[self class] defaultCellSize];
    _titleLabel.preferredMaxLayoutWidth = defaultSize.width - [_metricDict[@"sideBuffer1"] floatValue] -[_metricDict[@"labelImageSizeWith"] integerValue] - 5 - [_metricDict[@"sideBuffer2"] integerValue];
}

// 第三步、tableview代理函数,返回当前显示cell的方法,取出当前cell即将显示的实体对象,然后调用cell对象的 设置数据方法

- (void)setupDataItem:(id)data {

    if ([data isKindOfClass:[ZSYEntityModule class]]) {
        _entity = (ZSYEntityModule *)data;
        _titleLabel.text = _entity.title;

        //对当前传入实体对象,增加或修改,cell.contentView.subviews
        [self customLayoutSubviews];

        //马上执行系统的 updateConstraints方法
        [self setNeedsUpdateConstraints];
        [self updateConstraintsIfNeeded];
    }
}

- (void)customLayoutSubviews {

    //取出当前要显示的图片张数,依次创建subview,并添加到cell.contentView
    for (NSString *url in _entity.hots) {

        __block UIImageView *subView = [[UIImageView alloc] init];
        [self.contentView addSubview:subView];

        UILabel *icon = [self newIcon];
        [subView addSubview:icon];

        [icon mas_makeConstraints:^(MASConstraintMaker *make) {
            make.centerY.mas_equalTo(subView.mas_top);
            make.right.mas_equalTo(subView.mas_right).offset(-5);
            make.size.mas_equalTo(CGSizeMake(Cordius*2 , Cordius*2));
        }];

        //测试设置图片
//        if ([url containsString:@"http"]) {
//            [subView sd_setImageWithURL:[NSURL URLWithString:url]
//                       placeholderImage:[UIImage imageNamed:@"blankpage_image_Hi"]
//                                options:SDWebImageProgressiveDownload];
//        } else {
            [subView setImage:[UIImage imageNamed:url]];
//        }
       
        _lastView = subView;
        [_subViews addObject:subView];
    }
}

// 最后就是重写系统方法,更新约束

- (void)updateConstraints {
    @weakify(self);

    CGFloat width = [_metricDict[@"labelImageSizeWith"] integerValue];
    CGFloat height= [_metricDict[@"labelImageSizeHeight"] integerValue];
    [_titleLeftImageView mas_makeConstraints:^(MASConstraintMaker *make) {
        @strongify(self);
        make.top.mas_equalTo(self.contentView.mas_top).offset(14);
        make.left.mas_equalTo(self.contentView.mas_left).offset(12);
        make.size.mas_equalTo(CGSizeMake(width, height));
    }];

    [_titleLabel mas_makeConstraints:^(MASConstraintMaker *make) {
        @strongify(self);
        make.top.mas_equalTo(self.contentView.mas_top).offset(12).priority(751);
        make.left.mas_equalTo(self.titleLeftImageView.mas_right).offset(5);
    }];

    __block UIImageView *last = nil;
    for (int i = 0; i < _subViews.count; i++) {
        UIImageView *subView = _subViews[i];

        [subView mas_makeConstraints:^(MASConstraintMaker *make) {
            @strongify(self);
            make.left.mas_equalTo(self.contentView.mas_left).offset(10);
            make.right.mas_equalTo(self.contentView.mas_right).offset(-10);
            if (last) {
                make.top.mas_equalTo(last.mas_bottom).offset(Cordius+2).priority(749);
            } else {
                make.top.mas_equalTo(self.titleLabel.mas_bottom).offset(15).priority(749);
            }
            make.height.mas_equalTo(@180);
        }];

        last = subView;
    }

    [self.contentView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.bottom.mas_equalTo(last.mas_bottom).offset(10);
    }];

    //一定要写
    [super updateConstraints];
}


AutoLayout五、使用Masonry完成UITableViewCell的自适应高度

标签:des   高度自适应   class   style   log   com   http   使用   src   

原文:http://www.cnblogs.com/xiongzenghui/p/4684763.html
猜你会喜欢....

Copyright © 2015 www.wahenzan.com 哇!很赞 版权所有 浙ICP备14030256号-1 Power by DedeCms

浙公网安备 33010602005986号

声明:本站所有文章除标明原创外,均来自网络转载,版权归原作者所有,如果有侵犯到您的权益,请联系本站删除 网站管理员:758763728

360网站安全检测平台