iOS开发之计算动态cell的高度并缓存
项目中有个类似微博那样的动态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的高度并缓存的更多相关文章
- iOS开发总结-UITableView 自定义cell和动态计算cell的高度
UITableView cell自定义头文件:shopCell.h#import <UIKit/UIKit.h>@interface shopCell : UITableViewCell@ ...
- iOS开发——Autolayout下动态调整单元格高度
情景描述: 有时候我们希望更新某一个单元格的数据,通常的做法是使用reloadData方法更新整个单元格.但是对一些情况是不适用的或者说实现起来比较麻烦.比如说这种简单的"点开"一 ...
- iOS 开发中单元格cell高度自适应
高度自适应分下面两种情况 1.用代码自定义的cell 用代码自定义的cell,cell高度自定义需要我们手动的去计算每个cell的字符串高度.然后返回对应的高度即可. 2.用XIB 或者 StoreB ...
- iOS开发——C篇&动态内存分配
再C语言中关于内存是一个很重要的知识点,所以今天我就从c语言的内存分配开始为大家解析一下C语言再iOS开发中非常重要的一些知识. 1:malloc函数的介绍 C语言中开辟内存空间:malloc函数 再 ...
- iOS开发——C篇&动态内存分析
再C语言中关于内存是一个很重要的知识点,所以今天我就从c语言的内存分配开始为大家解析一下C语言再iOS开发中非常重要的一些知识. 1:malloc函数的介绍 C语言中开辟内存空间:malloc函数(堆 ...
- iOS开发UI篇—UITableviewcell的性能优化和缓存机制
iOS开发UI篇—UITableviewcell的性能问题 一.UITableviewcell的一些介绍 UITableView的每一行都是一个UITableViewCell,通过dataSource ...
- iOS开发 准确计算Coretext高度
- (int)getAttributedStringHeightWithString:(NSAttributedString *) string WidthValue:(int) width{ ...
- iOS UItableview 镶嵌 collectionView ,cell 自适应高度动态布局
最近在写这个功能,之前看到很多,可是需求一直没有涉及到,大致思路是有的,发现,网上的大部分都有缺陷和bug,我也是好无语啦啦啦,也不晓得是不是升级 了xcode,一样的代码,允许的效果都不一样,,,苦 ...
- ios开发――解决UICollectionView的cell间距与设置不符问题
在用UICollectionView展示数据时,有时我们希望将cell的间距调成一个我们想要的值,然后查API可以看到有这么一个属性: - (CGFloat)minimumInteritemSpaci ...
随机推荐
- java 值传递和引用传递。
java中 基本类型的参数传递是值传递,即前后两个方法的变量不相干,被调方法参数值改变不影响调用方法的传参数值. 引用数据类型的参数传递是 传递的是参数的地址.即被调方法修改参数值会,调用方法里会跟着 ...
- Python学习入门基础教程(learning Python)--2.2 Python下的变量基础
变量的基本概念,变量可以这样去理解,变量是一个值,这个值存储在计算机的内存里.以网购为例,您在选购傻商品的时候,是在不同页面里选不同的商品,选好一件点击“放入购物车”,选完了再点击去结帐,这些商品的价 ...
- 初试PL/SQL并行编程
-----------------------------Cryking原创------------------------------ -----------------------转载请注明出处, ...
- 开源html5_kiwijs_helloworld
本次须要的下载文件已经共享出来 网盘地址 由于我使用的是黑苹果系统, window我就无视了. 开发工具使用 网盘里的 dmg :Sublime Text 打开开发工具后在helloworld中找到 ...
- NeHe OpenGL lession 4
// lession4.c #include <OpenGL/OpenGL.h> #include <GLUT/GLUT.h> #include <stdio.h> ...
- Mac OS使用技巧之十五:快捷方便的Mini Dock
Mini Dock是前面忘记了提,这里做一些补充. Mini Dock是Mac OSX的一个值得大书特书的亮点.尽管windows下也有类似的东西,但Mac下却提供了更为全面的功能.通过M ...
- C# inherit
Case:class A has a construct. class B is inherit from class A and B also has a construct. What's the ...
- plsql developer连接64位Oracle11g的解决方法
1)安装Oracle 11g 64位 2)安装32位的Oracle客户端( instantclient-basic-win32-11.2.0.1.0)下载地址:http://www.oracle.co ...
- Enze fourth day(循环语句 一)
哈喽,大家好.又到了总结知识的时间了.今天在云和学院自学了一下循环语句,下面是自己总的一些知识点. 先补充一下选择结构中的switch语句. 理论:switch语句是一种多分支选择语句,当需要测试大量 ...
- 如何在Eclipse中配置Tomcat(免安装版)
如何在Eclipse中配置Tomcat(免安装版) 2013-10-09 23:19wgelgrsh | 分类:JAVA相关 | 浏览642次 分享到: 2013-10-10 17:10提问者采纳 ...