第二篇、为UITableViewCell 高度自适应加速 缓存cell的高度
通过NSCache缓存已经算好的行高
@interface ZHCellHeightCalculator : NSObject //系统计算高度后缓存进cache -(void)setHeight:(CGFloat)height withCalculateheightModel:(ZHCalculateHeightModel *)model; //根据model hash 获取cache中的高度,如过无则返回-1 -(CGFloat)heightForCalculateheightModel:(ZHCalculateHeightModel *)model; //清空cache -(void)clearCaches; @end
#import "ZHCellHeightCalculator.h" @interface ZHCellHeightCalculator () @property (strong, nonatomic, readonly) NSCache *cache; @end @implementation ZHCellHeightCalculator #pragma mark - Init -(instancetype)init { self = [super init]; if (self) { [self defaultConfigure]; } return self; } -(void)defaultConfigure { NSCache *cache = [NSCache new]; cache.name = @"ZHCellHeightCalculator.cache"; cache.countLimit = 200; _cache = cache; } #pragma mark - NSObject - (NSString *)description { return [NSString stringWithFormat:@"<%@: cache=%@", [self class], self.cache]; } #pragma mark - Publci Methods -(void)clearCaches { [self.cache removeAllObjects]; } -(void)setHeight:(CGFloat)height withCalculateheightModel:(ZHCalculateHeightModel *)model { NSAssert(model != nil, @"Cell Model can't nil"); NSAssert(height >= 0, @"cell height must greater than or equal to 0"); [self.cache setObject:[NSNumber numberWithFloat:height] forKey:@(model.hash)]; } -(CGFloat)heightForCalculateheightModel:(ZHCalculateHeightModel *)model { NSNumber *cellHeightNumber = [self.cache objectForKey:@(model.hash)]; if (cellHeightNumber) { return [cellHeightNumber floatValue]; }else return -1; } @end
使用方式:
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { ZHCalculateHeightModel *model = model = [dataArray objectAtIndex:indexPath.row]; CGFloat height = [heightCalculator heightForCalculateheightModel:model]; if (height>0) { NSLog(@"cache height"); return height; }else{ NSLog(@"calculate height"); } ZHCalculateTableViewCell *cell = self.prototypeCell; cell.contentView.translatesAutoresizingMaskIntoConstraints = NO; [self configureCell:cell atIndexPath:indexPath];//必须先对Cell中的数据进行配置使动态计算时能够知道根据Cell内容计算出合适的高度 /*------------------------------重点这里必须加上contentView的宽度约束不然计算出来的高度不准确-------------------------------------*/ CGFloat contentViewWidth = CGRectGetWidth(self.tableView.bounds); NSLayoutConstraint *widthFenceConstraint = [NSLayoutConstraint constraintWithItem:cell.contentView attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0 constant:contentViewWidth]; [cell.contentView addConstraint:widthFenceConstraint]; // Auto layout engine does its math CGFloat fittingHeight = [cell.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize].height; [cell.contentView removeConstraint:widthFenceConstraint]; /*-------------------------------End------------------------------------*/ CGFloat cellHeight = fittingHeight+2*1/[UIScreen mainScreen].scale;//必须加上上下分割线的高度 [heightCalculator setHeight:cellHeight withCalculateheightModel:model]; return cellHeight; }