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 ...
随机推荐
- MVC-Easy-UI-datagrid-分页-查询
时间仓促,代码写的乱,莫怪,着影区不用理会(功能之外) <link href="@Url.Content("~/Content/Site.css")" r ...
- Windows Azure 网站 (WAWS) 中的服务器端包含 (SSI)
编辑人员注释:本文章由 Windows Azure 网站团队的项目经理Erez Benari 撰写. Windows Azure 网站客户普遍关心的一个问题是关于我们对服务器端包含(Server ...
- c++的正整数高精度加减乘除
数值计算之高精度加减乘除 一. 高精度正整数的高精度计算 1.加法 2.减法 减法和加法的最大区别在于:减法是从高位开始相减,而加法是从低位开始相加 3.乘法:用高精度加法实现 l 乘法的主 ...
- 如何让HTML的编写更具结构性
首先声明,我不是搞技术的,很多词汇写的不够专业,但作为一枚菜鸟,我站在菜鸟的角度,来讲述我在学习技术的过程中所遇到的问题,和解决的方案. 入门HTML还算简单,无非是先写好固定的三对开闭标签结构:ht ...
- js超简单日历
用原生js写了一个超级简单的日历.当做是练习js中的Date类型. 思路: 获取某个日期,根据年份计算出每个月的天数. 利用Date中的getDay()知道该月份的第一天为星期几. 循环创建表格,显示 ...
- Light OJ 1104 Birthday Pardo(生日悖论)
ime Limit:2000MS Memory Limit:32768KB 64bit IO Format:%lld & %llu Description Sometime ...
- _int64、long long 的区别
C++的64位整数[原]by 赤兔 http://baike.baidu.com/view/1235293.htm 在做ACM题时,经常都会遇到一些比较大的整数.而常用的内置整数类型常常显得太小了:其 ...
- linux下出现java.net.UnknownHostException
项目部署在win环境下没问题,但是在迁移生产环境的时候出现Java.net.UnknowHostException 原因在于etc/hosts 文件没有配置域名映射,使用vi编辑器加上服务器ip 以及 ...
- Servlet乘法表学习笔记
一.控制台实现乘法表 package com.shanrengo; import java.io.IOException; import java.io.PrintWriter; import jav ...
- [置顶] P2P之我见,关于打洞的学问-------开篇
最近忙项目,有点累,无暇顾急博客,4月份本来想写写流媒体的文章,结果回家休了两个月回深圳后,接了P2P的项目,那就开始P2P吧. P2P起源于美国大学生Shawn Fanning 写的一个分享软件Na ...