#import <Foundation/Foundation.h> @protocol ZSYAutoLayoutCellProtocol; static CGFloat ZSYDynamicTableViewCellAccessoryWidth = 33; //这个数组用来保存全部类型的自动布局的Cell类的一个对象,用于后面计算cell高度 static NSMutableArray *cellArray; //先传出保存的cell对象,而后再用调用者返回设置了全部显示数据的cell对象,用于计算cell高度须要 typedef id (^setupCellBlock)(id<ZSYAutoLayoutCellProtocol> cellToSetup); @protocol ZSYAutoLayoutCellProtocol <NSObject> //全部cell设置数据 - (void)setupDataItem:(id)data; //计算cell高度 + (CGSize)sizeForCellWithDefaultSize:(CGSize)defaultSize setupCellBlock:(setupCellBlock)block; @end
- (void)setupDataItem:(id)data { //这个方法子类cell重写,将实体对象设置给cell.contentView.subviews } + (CGSize)sizeForCellWithDefaultSize:(CGSize)defaultSize setupCellBlock:(setupCellBlock)block { __block UITableViewCell *cell = nil; //查看静态数组内是否已经存在当前Cell类的一个对象 [cellArray enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { if ([obj isKindOfClass:[[self class] class]]) { cell = obj; *stop = YES; } }]; //若是不存在,建立一个当前Cell类型的对象,并保存到数组。后续计算当前Cell类型对象的高度时,直接使用这个保存的Cell对象 if (!cell) { cell = [[[self class] alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"XZHAutoLayoutCellIdentifier"]; cell.frame = CGRectMake(0, 0, defaultSize.width, defaultSize.height); [cellArray addObject:cell]; } //获取到设置了属性值的cell对象[1.先回传出去 2.再接收Block的一个返回值cell对象] cell = block((id<ZSYAutoLayoutCellProtocol>) cell); //获取到cell对象的 CGSize // [cell.contentView layoutIfNeeded]; CGSize size = [cell.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize]; size.width = MAX(defaultSize.width, size.width); size.height = size.height + 1.0f; return size; }
// 实现接口定义的设置实体类对象的方法 - (void)setupDataItem:(id)data { if ([data isKindOfClass:[ZSYEntityModule class]]) { _entity = (ZSYEntityModule *)data; _titleLabel.text = _entity.title; [_contentImageView sd_setImageWithURL:[NSURL URLWithString:_entity.imageURL] placeholderImage:[UIImage imageNamed:@"blankpage_image_Hi"] options:SDWebImageProgressiveDownload]; //UILabel写上这一句 [_titleLabel layoutIfNeeded]; } }
//给Cell.contentView.subviews分别设置约束,使用VFL - (void)initSubviews { self.backgroundColor = [UIColor whiteColor]; self.accessoryType = UITableViewCellAccessoryNone; self.accessoryView = nil; self.selectionStyle = UITableViewCellSelectionStyleNone; [self.contentView setAutoresizingMask:UIViewAutoresizingFlexibleHeight]; _titleLeftImageView = [[UIImageView alloc] init]; _titleLeftImageView.image = [UIImage imageNamed:@"icon_title"]; _titleLeftImageView.translatesAutoresizingMaskIntoConstraints = NO; _titleLeftImageView.contentMode = UIViewContentModeScaleAspectFill; _titleLabel = [[UILabel alloc] init]; _titleLabel.numberOfLines = 0; _titleLabel.lineBreakMode = NSLineBreakByWordWrapping; _titleLabel.translatesAutoresizingMaskIntoConstraints = NO; _titleLabel.font = [UIFont fontWithName:@"HelveticaNeue-Bold" size:15]; _titleLabel.textColor = [UIColor hex:@"#514647"]; _contentImageView = [[UIImageView alloc] init]; _contentImageView.translatesAutoresizingMaskIntoConstraints = NO; [self.contentView addSubview:_titleLeftImageView]; [self.contentView addSubview:_titleLabel]; [self.contentView addSubview:_contentImageView]; NSDictionary *viewDict = NSDictionaryOfVariableBindings(_titleLeftImageView, _titleLabel, _contentImageView); NSDictionary *metricDict = @{@"sideBuffer1" : @16, @"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}; NSString *vfl = @"H:|-sideBuffer1-[_titleLeftImageView(labelImageSizeWith)]-5-[_titleLabel]-sideBuffer2-|"; [self.contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:vfl options:0 metrics:metricDict views:viewDict]]; vfl = @"H:|-sideBuffer2-[_contentImageView]-sideBuffer2-|"; [self.contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:vfl options:0 metrics:metricDict views:viewDict]]; vfl = @"V:|-vertical_top_Buffer-[_titleLeftImageView]"; [self.contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:vfl options:0 metrics:metricDict views:viewDict]]; vfl = @"V:|-vertical_top_Buffer-[_titleLabel]-vertical_middle_Buffer-[_contentImageView(contentImageSizeHeight)]-vertical_bottom_Buffer-|"; [self.contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:vfl options:0 metrics:metricDict views:viewDict]]; // vfl = @"V:[_contentImageView(contentImageSizeHeight)]-vertical_bottom_Buffer-|"; // [self.contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:vfl options:0 metrics:metricDict views:viewDict]]; // [self.contentView addConstraint:[NSLayoutConstraint constraintWithItem:self.titleLeftImageView attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self.titleLabel attribute:NSLayoutAttributeTop multiplier:1 constant:0]]; [self.contentView addConstraint:[NSLayoutConstraint constraintWithItem:self.titleLeftImageView attribute:NSLayoutAttributeCenterY relatedBy:NSLayoutRelationEqual toItem:self.titleLabel attribute:NSLayoutAttributeCenterY multiplier:1 constant:0]]; // [self.contentView addConstraint:[NSLayoutConstraint constraintWithItem:self.titleLeftImageView attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:self.titleLabel attribute:NSLayoutAttributeBottom multiplier:1 constant:0]]; [self.titleLabel setContentCompressionResistancePriority:UILayoutPriorityRequired forAxis:UILayoutConstraintAxisVertical]; [self.titleLabel setContentCompressionResistancePriority:UILayoutPriorityDefaultLow forAxis:UILayoutConstraintAxisHorizontal]; //获取每一个cell重写后,本身的默认size CGSize defaultSize = [[self class] defaultCellSize]; //注意: 全部UILabel若是须要高度动态改变,必定要设置preferredMaxLayoutWidth最大宽度 self.titleLabel.preferredMaxLayoutWidth = defaultSize.width - [metricDict[@"sideBuffer1"] floatValue] -[metricDict[@"labelImageSizeWith"] integerValue] - 5 - [metricDict[@"sideBuffer2"] integerValue]; }
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { if (![[self cellClass] isDynamic]) { return [self cellDefaultHeight]; } __weak typeof(self) weakSelf = self; //默认 size CGSize defaultSize = [[self cellClass] defaultCellSize]; //计算后自适应的 size CGSize cellSize = [[self cellClass] sizeForCellWithDefaultSize:defaultSize setupCellBlock:^id(id<ZSYAutoLayoutCellProtocol> cellToSetup) { NSArray *dataList = [weakSelf dataSource]; if ([self sectionCount] == 1) {//一维数组 [cellToSetup setupDataItem:dataList[[indexPath row]]]; } else {//二惟数组 NSArray *sectionArray = dataList[indexPath.section]; id obj = sectionArray[indexPath.row]; [cellToSetup setupDataItem:obj]; } return cellToSetup; }]; return cellSize.height; }