项目中有个类似微博那样的动态cell,文字和图片的多少都不是确定的

刚开始使用autolayout,结果很多问题,最后我发现了一个框架 FDTemplateLayoutCell

写的很好,自动布局cell,但是最后还是出现了很多问题,或许是不适用这种情况

最后只能用frame布局了,但是FDTemplateLayoutCell的缓存机制还是值得借鉴的

说说我的做法

首先利用frameModel计算出cell height

这个过程省略

我说说这么缓存

和FD*一样,我写了一个UITableView的category

在这个category里面又写了一个类,CellHeightCache

定义了三个方法

//是否已经缓存了
- (BOOL)existsHeightForKey:(id<NSCopying>)key {
NSNumber *number = self.mutableCellHeightCaches[key];
return number && ![number isEqualToNumber:@-1];
}

//缓存高度,传入key
- (void)cacheHeight:(CGFloat)height byKey:(id<NSCopying>)key {
self.mutableCellHeightCaches[key] = @(height);
}

//传入key获得高度
- (CGFloat)heightForKey:(id<NSCopying>)key {
#if CGFLOAT_IS_DOUBLE
return [self.mutableCellHeightCaches[key] doubleValue];
#else
return [self.mutableCellHeightCaches[key] floatValue];
#endif
}

 

然后我在UITableView的分类里面写了两个方法

一个传入key获得高度,一个传入key和高度 缓存高度

- (CGFloat)getCellHeightCacheWithCacheKey:(NSString *)cacheKey
{
if (!cacheKey) {
return 0;
} //如果已经存在cell height 则返回
if ([self.cellHeightCache existsHeightForKey:cacheKey]) {
CGFloat cachedHeight = [self.cellHeightCache heightForKey:cacheKey];
return cachedHeight;
} else {
return 0;
}
} //缓存cell的高度
- (void)setCellHeightCacheWithCellHeight:(CGFloat)cellHeight CacheKey:(NSString *)cacheKey
{
[self.cellHeightCache cacheHeight:cellHeight byKey:cacheKey];
}

他们都调用了这个方法

- (CellHeightCache *)cellHeightCache
{
CellHeightCache *cache = objc_getAssociatedObject(self, _cmd);
if (!cache) {
cache = [CellHeightCache new];
objc_setAssociatedObject(self, _cmd, cache, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
return cache;
}

这两个方法用的是OC中runtime方法,原理是两个文件关联方法,和上层的存储方法> 差不多,传入value和key对应,取出也是根据key取出value
object传入self即可

1.设置关联方法

//传入object和key和value,policy
//policy即存储方式,和声明使用几种属性大致相同,有copy,retain,copy,retain_nonatomic,assign 五种) void objc_setAssociatedObject(id object, const void *key, id value, objc_AssociationPolicy policy)

  

2.取出方法

//传入object和key返回value
id objc_getAssociatedObject(id object, const void *key)

这里是先获得缓存对象,如果为空的还就新创建一个,再进行关联。
这里用到了_cmd
_cmd是隐藏的参数,代表当前方法的selector,他和self一样都是每个方法调用时都会传入的参数,动态运行时会提及如何传的这两个参数。

经常和关联方法搭配一起用

然后我在heightForRowAtIndexPath里面调用了

    CGFloat cellHeight = [tableView getCellHeightCacheWithCacheKey:statusFrame.identifier];
NSLog(@"从缓存取出来的-----%f",cellHeight); if(!cellHeight){
statusFrame.status = status;
cellHeight = statusFrame.cellHeight;
[tableView setCellHeightCacheWithCellHeight:cellHeight CacheKey:statusFrame.identifier];
}

这样缓存高度就搞定了。

实际效果

代码地址

https://github.com/AscenZ/YBDynamicCell

我写的一篇 解析FDTempLayoutCell的文章

在公众号

iOS开发之计算动态cell的高度并缓存的更多相关文章

  1. iOS开发总结-UITableView 自定义cell和动态计算cell的高度

    UITableView cell自定义头文件:shopCell.h#import <UIKit/UIKit.h>@interface shopCell : UITableViewCell@ ...

  2. iOS开发——Autolayout下动态调整单元格高度

    情景描述: 有时候我们希望更新某一个单元格的数据,通常的做法是使用reloadData方法更新整个单元格.但是对一些情况是不适用的或者说实现起来比较麻烦.比如说这种简单的"点开"一 ...

  3. iOS 开发中单元格cell高度自适应

    高度自适应分下面两种情况 1.用代码自定义的cell 用代码自定义的cell,cell高度自定义需要我们手动的去计算每个cell的字符串高度.然后返回对应的高度即可. 2.用XIB 或者 StoreB ...

  4. iOS开发——C篇&动态内存分配

    再C语言中关于内存是一个很重要的知识点,所以今天我就从c语言的内存分配开始为大家解析一下C语言再iOS开发中非常重要的一些知识. 1:malloc函数的介绍 C语言中开辟内存空间:malloc函数 再 ...

  5. iOS开发——C篇&动态内存分析

    再C语言中关于内存是一个很重要的知识点,所以今天我就从c语言的内存分配开始为大家解析一下C语言再iOS开发中非常重要的一些知识. 1:malloc函数的介绍 C语言中开辟内存空间:malloc函数(堆 ...

  6. iOS开发UI篇—UITableviewcell的性能优化和缓存机制

    iOS开发UI篇—UITableviewcell的性能问题 一.UITableviewcell的一些介绍 UITableView的每一行都是一个UITableViewCell,通过dataSource ...

  7. iOS开发 准确计算Coretext高度

    - (int)getAttributedStringHeightWithString:(NSAttributedString *)  string  WidthValue:(int) width{   ...

  8. iOS UItableview 镶嵌 collectionView ,cell 自适应高度动态布局

    最近在写这个功能,之前看到很多,可是需求一直没有涉及到,大致思路是有的,发现,网上的大部分都有缺陷和bug,我也是好无语啦啦啦,也不晓得是不是升级 了xcode,一样的代码,允许的效果都不一样,,,苦 ...

  9. ios开发――解决UICollectionView的cell间距与设置不符问题

    在用UICollectionView展示数据时,有时我们希望将cell的间距调成一个我们想要的值,然后查API可以看到有这么一个属性: - (CGFloat)minimumInteritemSpaci ...

随机推荐

  1. 关于Class.forName(“com.mysql.jdbc.Driver”)--转

    传统的使用jdbc来访问数据库的流程为:Class.forName(“com.mysql.jdbc.Driver”);String url = “jdbc:mysql://localhost:3306 ...

  2. 分组求和SQL示例

        1.ROLLUP和CUBE函数,自动汇总数据      select * from test_tbl的数据这样的      col_a col_b col_c      ---- ----- ...

  3. Java解析器

    http://www.infoq.com/cn/articles/HIgh-Performance-Parsers-in-Java-V2?utm_source=infoq&utm_medium ...

  4. Flex疑难小杂症

    本文主要解决Flex中一些小问题,收集一些小技巧(来自网络及个人经验) flex自动换行问题  有时候由于label .button等控件中需要用到text属性显示出文本,文本太长就涉及到换行问题,解 ...

  5. java--折半查找

    /* 折半查找 */ class TwoSearch { //折半查找可以提高效率,但必须得保证是有序的数组 public static int halfSearch(int[] arr,int ke ...

  6. poj1201 Intervals【差分约束+SPFA】

    转载请注明出处,谢谢:http://www.cnblogs.com/KirisameMarisa/p/4303365.html   ---by 墨染之樱花 题目链接:http://poj.org/pr ...

  7. JavaScript 高级程序设计(第3版)笔记——chapter5:引用类型(基本包装类型部分)

    一.介绍 为了方便操作基本类型值,ECMAScript还提供了3个特殊的引用类型:Boolean, Number, String. 实际上,每当读取一个基本类型值得时候,后台就会创建一个对应的基本包装 ...

  8. 学习MVC遇到的问题

    修改电脑上的DNS配置: Opendns 首选DNS服务器和备用DNS服务器分别设置为208.67.222.222和208.67.220.220 google的8.8.8.8 首选DNS服务器和备用D ...

  9. [译]Stairway to Integration Services Level 12 - 高级日志配置

    介绍 本文中,我们将结合之前学习的时间冒泡,日志记录,以及复制模型.建立一个自定义的SSIS包日志模型. SSIS Task事件回顾    Reviewing SSIS Task Events 在做实 ...

  10. vim: 字符串替换

    :s/str1/str2/ 替换当前行第一个 str1 为 str2:s/str1/str2/g 替换当前行所有 str1 为 str2 ( 注意,  s/xx/xxx/g 语句从s开始,中间的空格视 ...