猎豆优选

UITableView+SDAutoTableViewCellHeight.m 20KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538
  1. //
  2. // UITableView+SDAutoTableViewCellHeight.m
  3. // SDAutoLayout 测试 Demo
  4. //
  5. // Created by aier on 15/11/1.
  6. // Copyright © 2015年 gsd. All rights reserved.
  7. //
  8. /*
  9. *********************************************************************************
  10. * *
  11. * 在您使用此自动布局库的过程中如果出现bug请及时以以下任意一种方式联系我们,我们会及时修复bug并 *
  12. * 帮您解决问题。 *
  13. * QQ : 2689718696(gsdios) *
  14. * Email : gsdios@126.com *
  15. * GitHub: https://github.com/gsdios *
  16. * 新浪微博:GSD_iOS *
  17. * *
  18. *********************************************************************************
  19. */
  20. #import "UITableView+SDAutoTableViewCellHeight.h"
  21. #import <objc/runtime.h>
  22. @interface SDCellAutoHeightManager ()
  23. @property (nonatomic, weak) UITableView *modelTableview;
  24. @end
  25. @implementation SDCellAutoHeightManager
  26. {
  27. NSMutableDictionary *_cacheDictionary;
  28. NSMutableDictionary *_modelCellsDict;
  29. }
  30. - (instancetype)init
  31. {
  32. if (self = [super init]) {
  33. [self setup];
  34. }
  35. return self;
  36. }
  37. - (instancetype)initWithCellClass:(Class)cellClass tableView:(UITableView *)tableView
  38. {
  39. if (self = [super init]) {
  40. [self setup];
  41. self.modelTableview = tableView;
  42. [self registerCellWithCellClass:cellClass];
  43. }
  44. return self;
  45. }
  46. - (instancetype)initWithCellClasses:(NSArray *)cellClassArray tableView:(UITableView *)tableView
  47. {
  48. if (self = [super init]) {
  49. [self setup];
  50. self.modelTableview = tableView;
  51. [cellClassArray enumerateObjectsUsingBlock:^(Class obj, NSUInteger idx, BOOL *stop) {
  52. [self registerCellWithCellClass:obj];
  53. }];
  54. }
  55. return self;
  56. }
  57. - (void)setup
  58. {
  59. _cacheDictionary = [NSMutableDictionary new];
  60. _modelCellsDict = [NSMutableDictionary new];
  61. }
  62. - (void)registerCellWithCellClass:(Class)cellClass
  63. {
  64. [_modelTableview registerClass:cellClass forCellReuseIdentifier:NSStringFromClass(cellClass)];
  65. self.modelCell = [_modelTableview dequeueReusableCellWithIdentifier:NSStringFromClass(cellClass)];
  66. if (!self.modelCell.contentView.subviews.count) {
  67. NSString *path = [[NSBundle mainBundle] pathForResource:[NSString stringWithFormat:@"%@.nib", NSStringFromClass(cellClass)] ofType:nil];
  68. if (path) {
  69. self.modelCell = nil;
  70. [_modelTableview registerNib:[UINib nibWithNibName:NSStringFromClass(cellClass) bundle:nil] forCellReuseIdentifier:NSStringFromClass(cellClass)];
  71. self.modelCell = [_modelTableview dequeueReusableCellWithIdentifier:NSStringFromClass(cellClass)];
  72. }
  73. }
  74. if (self.modelCell) {
  75. [_modelCellsDict setObject:self.modelCell forKey:NSStringFromClass(cellClass)];
  76. }
  77. }
  78. + (instancetype)managerWithCellClass:(Class)cellClass tableView:(UITableView *)tableView
  79. {
  80. SDCellAutoHeightManager *manager = [[self alloc] initWithCellClass:cellClass tableView:tableView];
  81. return manager;
  82. }
  83. - (UITableViewCell *)modelCell
  84. {
  85. if (_modelCell.contentView.tag != kSDModelCellTag) {
  86. _modelCell.contentView.tag = kSDModelCellTag;
  87. }
  88. return _modelCell;
  89. }
  90. - (NSDictionary *)heightCacheDict
  91. {
  92. return _cacheDictionary;
  93. }
  94. - (void)clearHeightCache
  95. {
  96. [_cacheDictionary removeAllObjects];
  97. [_subviewFrameCacheDict removeAllObjects];
  98. }
  99. - (NSString *)cacheKeyForIndexPath:(NSIndexPath *)indexPath
  100. {
  101. return [NSString stringWithFormat:@"%ld-%ld", (long)indexPath.section, (long)indexPath.row];
  102. }
  103. - (void)clearHeightCacheOfIndexPaths:(NSArray *)indexPaths
  104. {
  105. [indexPaths enumerateObjectsUsingBlock:^(NSIndexPath *indexPath, NSUInteger idx, BOOL *stop) {
  106. NSString *cacheKey = [self cacheKeyForIndexPath:indexPath];
  107. [_cacheDictionary removeObjectForKey:cacheKey];
  108. [_subviewFrameCacheDict removeObjectForKey:cacheKey];
  109. }];
  110. }
  111. - (void)deleteThenResetHeightCache:(NSIndexPath *)indexPathToDelete
  112. {
  113. NSString *cacheKey = [self cacheKeyForIndexPath:indexPathToDelete];
  114. [_cacheDictionary removeObjectForKey:cacheKey];
  115. [_subviewFrameCacheDict removeObjectForKey:cacheKey];
  116. long sectionOfToDeleteItem = indexPathToDelete.section;
  117. long rowOfToDeleteItem = indexPathToDelete.row;
  118. NSMutableDictionary *tempHeightCacheDict = [NSMutableDictionary new];
  119. NSMutableDictionary *tempFrameCacheDict = [NSMutableDictionary new];
  120. for (NSString *key in _cacheDictionary.allKeys) {
  121. NSArray *res = [key componentsSeparatedByString:@"-"];
  122. long section = [res.firstObject integerValue];
  123. long row = [res.lastObject integerValue];
  124. if (section == sectionOfToDeleteItem && row > rowOfToDeleteItem) {
  125. NSNumber *heightCache = _cacheDictionary[key];
  126. NSArray *frameCache = _subviewFrameCacheDict[key];
  127. NSString *newKey = [NSString stringWithFormat:@"%ld-%ld", section, (row - 1)];
  128. [tempHeightCacheDict setValue:heightCache forKey:newKey];
  129. [tempFrameCacheDict setValue:frameCache forKey:newKey];
  130. [_cacheDictionary removeObjectForKey:key];
  131. [_subviewFrameCacheDict removeObjectForKey:key];
  132. }
  133. }
  134. [_cacheDictionary addEntriesFromDictionary:tempHeightCacheDict];
  135. [_subviewFrameCacheDict addEntriesFromDictionary:tempFrameCacheDict];
  136. }
  137. - (void)insertNewDataAtTheBeginingOfSection:(NSInteger)section newDataCount:(NSInteger)count
  138. {
  139. NSMutableDictionary *tempHeightCacheDict = [NSMutableDictionary new];
  140. NSMutableDictionary *tempFrameCacheDict = [NSMutableDictionary new];
  141. for (NSString *key in _cacheDictionary.allKeys) {
  142. NSArray *res = [key componentsSeparatedByString:@"-"];
  143. long originalSection = [res.firstObject integerValue];
  144. long row = [res.lastObject integerValue];
  145. if (originalSection == section) {
  146. NSNumber *heightCache = _cacheDictionary[key];
  147. NSArray *frameCache = _subviewFrameCacheDict[key];
  148. NSString *newKey = [NSString stringWithFormat:@"%ld-%ld", originalSection, (row + count)];
  149. [tempHeightCacheDict setValue:heightCache forKey:newKey];
  150. [tempFrameCacheDict setValue:frameCache forKey:newKey];
  151. [_cacheDictionary removeObjectForKey:key];
  152. [_subviewFrameCacheDict removeObjectForKey:key];
  153. }
  154. }
  155. [_cacheDictionary addEntriesFromDictionary:tempHeightCacheDict];
  156. [_subviewFrameCacheDict addEntriesFromDictionary:tempFrameCacheDict];
  157. }
  158. - (void)insertNewDataAtIndexPaths:(NSArray *)indexPaths
  159. {
  160. NSMutableDictionary *sectionsdict = [NSMutableDictionary new];
  161. for (NSIndexPath *indexPath in indexPaths) {
  162. NSString *sectionkey = [@(indexPath.section) stringValue];
  163. if (![sectionsdict objectForKey:sectionkey]) {
  164. [sectionsdict setValue:[NSMutableArray new] forKey:sectionkey];
  165. }
  166. NSMutableArray *arr = sectionsdict[sectionkey];
  167. [arr addObject:indexPath];
  168. }
  169. for (NSString *sectionkey in sectionsdict.allKeys) {
  170. NSMutableArray *tempHeightCaches = [NSMutableArray new];
  171. NSMutableArray *tempFrameCaches = [NSMutableArray new];
  172. NSInteger section = [sectionkey integerValue];
  173. NSInteger rowCount = [self.modelTableview numberOfRowsInSection:section];
  174. if (rowCount <= 0) {
  175. continue;
  176. } else {
  177. for (int i = 0; i < rowCount; i++) {
  178. [tempHeightCaches addObject:[NSNull null]];
  179. [tempFrameCaches addObject:[NSNull null]];
  180. }
  181. }
  182. for (NSString *key in _cacheDictionary.allKeys) {
  183. NSArray *res = [key componentsSeparatedByString:@"-"];
  184. long originalSection = [res.firstObject integerValue];
  185. long row = [res.lastObject integerValue];
  186. if (originalSection == section) {
  187. NSNumber *heightCache = _cacheDictionary[key];
  188. NSArray *frameCache = _subviewFrameCacheDict[key];
  189. [tempHeightCaches setObject:heightCache atIndexedSubscript:row];
  190. [tempFrameCaches setObject:frameCache atIndexedSubscript:row];
  191. [_cacheDictionary removeObjectForKey:key];
  192. [_subviewFrameCacheDict removeObjectForKey:key];
  193. }
  194. }
  195. NSMutableArray *objsToInsert = [NSMutableArray new];
  196. NSMutableIndexSet *indexSet = [NSMutableIndexSet new];
  197. NSArray *indexPaths = sectionsdict[sectionkey];
  198. [indexPaths enumerateObjectsUsingBlock:^(NSIndexPath *obj, NSUInteger idx, BOOL *stop) {
  199. [objsToInsert addObject:[NSNull null]];
  200. [indexSet addIndex:obj.row];
  201. }];
  202. [tempHeightCaches insertObjects:objsToInsert atIndexes:indexSet];
  203. [tempFrameCaches insertObjects:objsToInsert atIndexes:indexSet];
  204. [tempHeightCaches enumerateObjectsUsingBlock:^(NSNumber *heightCache, NSUInteger idx, BOOL *stop) {
  205. if (![heightCache isKindOfClass:[NSNull class]]) {
  206. NSString *key = [NSString stringWithFormat:@"%zd-%zd", section, idx];
  207. [_cacheDictionary setValue:heightCache forKey:key];
  208. [_subviewFrameCacheDict setValue:[tempFrameCaches objectAtIndex:idx] forKey:key];
  209. }
  210. }];
  211. }
  212. }
  213. - (NSNumber *)heightCacheForIndexPath:(NSIndexPath *)indexPath
  214. {
  215. /*
  216. 如果程序卡在了这里很可能是由于你用了“dequeueReusableCellWithIdentifier:forIndexPath:”方法来重用cell,换成““dequeueReusableCellWithIdentifier:”(不带IndexPath)方法即可解决
  217. */
  218. NSString *cacheKey = [self cacheKeyForIndexPath:indexPath];
  219. return (NSNumber *)[_cacheDictionary objectForKey:cacheKey];
  220. }
  221. - (CGFloat)cellHeightForIndexPath:(NSIndexPath *)indexPath model:(id)model keyPath:(NSString *)keyPath
  222. {
  223. NSNumber *cacheHeight = [self heightCacheForIndexPath:indexPath];
  224. if (cacheHeight) {
  225. return [cacheHeight floatValue];
  226. } else {
  227. if (!self.modelCell) {
  228. return 0;
  229. }
  230. if (self.modelTableview && self.modelTableview != self.modelCell.sd_tableView) {
  231. self.modelCell.sd_tableView = self.modelTableview;
  232. }
  233. self.modelCell.sd_indexPath = indexPath;
  234. if (model && keyPath) {
  235. [self.modelCell setValue:model forKey:keyPath];
  236. } else if (self.cellDataSetting) {
  237. self.cellDataSetting(self.modelCell);
  238. }
  239. #ifdef SDDebugWithAssert
  240. /*
  241. 如果程序卡在了这里说明你的cell还没有调用“setupAutoHeightWithBottomView:(UIView *)bottomView bottomMargin:(CGFloat)bottomMargin”方法或者你传递的bottomView为nil,请检查并修改。例:
  242. //注意:bottomView不能为nil
  243. [cell setupAutoHeightWithBottomView:bottomView bottomMargin:bottomMargin];
  244. */
  245. NSAssert(self.modelCell.sd_bottomViewsArray.count, @">>>>>> 你的cell还没有调用“setupAutoHeightWithBottomView:(UIView *)bottomView bottomMargin:(CGFloat)bottomMargin”方法或者你传递的bottomView为nil,请检查并修改");
  246. #endif
  247. [self.modelCell.contentView layoutSubviews];
  248. NSString *cacheKey = [self cacheKeyForIndexPath:indexPath];
  249. [_cacheDictionary setObject:@(self.modelCell.autoHeight) forKey:cacheKey];
  250. if (self.modelCell.sd_indexPath && self.modelCell.sd_tableView) {
  251. if (self.modelCell.contentView.shouldReadjustFrameBeforeStoreCache) {
  252. self.modelCell.contentView.height_sd = self.modelCell.autoHeight;
  253. [self.modelCell.contentView layoutSubviews];
  254. }
  255. [self.modelCell.contentView.autoLayoutModelsArray enumerateObjectsUsingBlock:^(SDAutoLayoutModel *model, NSUInteger idx, BOOL *stop) {
  256. [self.modelTableview.cellAutoHeightManager setSubviewFrameCache:model.needsAutoResizeView.frame WithIndexPath:self.modelCell.sd_indexPath];
  257. }];
  258. }
  259. return self.modelCell.autoHeight;
  260. }
  261. }
  262. - (CGFloat)cellHeightForIndexPath:(NSIndexPath *)indexPath model:(id)model keyPath:(NSString *)keyPath cellClass:(Class)cellClass
  263. {
  264. if (![self.modelCell isKindOfClass:cellClass]) {
  265. self.modelCell = nil;
  266. self.modelCell = [_modelCellsDict objectForKey:NSStringFromClass(cellClass)];
  267. if (!self.modelCell) {
  268. [self registerCellWithCellClass:cellClass];
  269. }
  270. _modelCell.contentView.tag = kSDModelCellTag;
  271. }
  272. if (self.modelCell.contentView.width_sd != self.contentViewWidth) {
  273. _modelCell.contentView.width_sd = self.contentViewWidth;
  274. }
  275. return [self cellHeightForIndexPath:indexPath model:model keyPath:keyPath];
  276. }
  277. - (void)setContentViewWidth:(CGFloat)contentViewWidth
  278. {
  279. if (_contentViewWidth == contentViewWidth) return;
  280. CGFloat lastContentViewWidth = _contentViewWidth;
  281. _contentViewWidth = contentViewWidth;
  282. self.modelCell.contentView.width_sd = self.contentViewWidth;
  283. if (lastContentViewWidth > 0) {
  284. [_subviewFrameCacheDict removeAllObjects];
  285. dispatch_async(dispatch_get_main_queue(), ^{
  286. [self clearHeightCache];
  287. [self.modelTableview reloadData];
  288. });
  289. }
  290. }
  291. - (void)setSubviewFrameCache:(CGRect)rect WithIndexPath:(NSIndexPath *)indexPath
  292. {
  293. if (!self.subviewFrameCacheDict) {
  294. self.subviewFrameCacheDict = [NSMutableDictionary new];
  295. }
  296. NSString *cacheKey = [self cacheKeyForIndexPath:indexPath];
  297. NSMutableArray *caches = [self.subviewFrameCacheDict objectForKey:cacheKey];
  298. if (!caches) {
  299. caches = [NSMutableArray new];
  300. [self.subviewFrameCacheDict setValue:caches forKey:cacheKey];
  301. }
  302. [caches addObject:[NSValue valueWithCGRect:rect]];
  303. }
  304. - (NSMutableArray *)subviewFrameCachesWithIndexPath:(NSIndexPath *)indexPath
  305. {
  306. NSString *cacheKey = [self cacheKeyForIndexPath:indexPath];
  307. return [self.subviewFrameCacheDict valueForKey:cacheKey];
  308. }
  309. @end
  310. @implementation UITableView (SDAutoTableViewCellHeight)
  311. + (void)load {
  312. static dispatch_once_t onceToken;
  313. dispatch_once(&onceToken, ^{
  314. NSArray *selStringsArray = @[@"reloadData", @"reloadRowsAtIndexPaths:withRowAnimation:", @"deleteRowsAtIndexPaths:withRowAnimation:", @"insertRowsAtIndexPaths:withRowAnimation:"];
  315. [selStringsArray enumerateObjectsUsingBlock:^(NSString *selString, NSUInteger idx, BOOL *stop) {
  316. NSString *mySelString = [@"sd_" stringByAppendingString:selString];
  317. Method originalMethod = class_getInstanceMethod(self, NSSelectorFromString(selString));
  318. Method myMethod = class_getInstanceMethod(self, NSSelectorFromString(mySelString));
  319. method_exchangeImplementations(originalMethod, myMethod);
  320. }];
  321. });
  322. }
  323. - (void)sd_reloadData
  324. {
  325. if (!self.cellAutoHeightManager.shouldKeepHeightCacheWhenReloadingData) {
  326. [self.cellAutoHeightManager clearHeightCache];
  327. }
  328. [self sd_reloadData];
  329. self.cellAutoHeightManager.shouldKeepHeightCacheWhenReloadingData = NO;
  330. }
  331. - (void)sd_reloadRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation
  332. {
  333. [self.cellAutoHeightManager clearHeightCacheOfIndexPaths:indexPaths];
  334. [self sd_reloadRowsAtIndexPaths:indexPaths withRowAnimation:animation];
  335. }
  336. - (void)sd_deleteRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation
  337. {
  338. for (NSIndexPath *indexPath in indexPaths) {
  339. [self.cellAutoHeightManager deleteThenResetHeightCache:indexPath];
  340. }
  341. [self sd_deleteRowsAtIndexPaths:indexPaths withRowAnimation:animation];
  342. }
  343. - (void)sd_insertRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation
  344. {
  345. [self.cellAutoHeightManager insertNewDataAtIndexPaths:indexPaths];
  346. [self sd_insertRowsAtIndexPaths:indexPaths withRowAnimation:animation];
  347. }
  348. /*
  349. * 下一步即将实现的功能
  350. - (void)sd_moveRowAtIndexPath:(NSIndexPath *)indexPath toIndexPath:(NSIndexPath *)newIndexPath
  351. {
  352. [self sd_moveRowAtIndexPath:indexPath toIndexPath:newIndexPath];
  353. }
  354. */
  355. - (CGFloat)cellHeightForIndexPath:(NSIndexPath *)indexPath model:(id)model keyPath:(NSString *)keyPath cellClass:(Class)cellClass contentViewWidth:(CGFloat)contentViewWidth
  356. {
  357. self.cellAutoHeightManager.modelTableview = self;
  358. self.cellAutoHeightManager.contentViewWidth = contentViewWidth;
  359. return [self.cellAutoHeightManager cellHeightForIndexPath:indexPath model:model keyPath:keyPath cellClass:cellClass];
  360. }
  361. - (CGFloat)cellHeightForIndexPath:(NSIndexPath *)indexPath cellClass:(__unsafe_unretained Class)cellClass cellContentViewWidth:(CGFloat)width cellDataSetting:(AutoCellHeightDataSettingBlock)cellDataSetting
  362. {
  363. self.cellDataSetting = cellDataSetting;
  364. return [self cellHeightForIndexPath:indexPath model:nil keyPath:nil cellClass:cellClass contentViewWidth:width];
  365. }
  366. - (void)reloadDataWithExistedHeightCache
  367. {
  368. self.cellAutoHeightManager.shouldKeepHeightCacheWhenReloadingData = YES;
  369. [self reloadData];
  370. }
  371. - (void)reloadDataWithInsertingDataAtTheBeginingOfSection:(NSInteger)section newDataCount:(NSInteger)count
  372. {
  373. self.cellAutoHeightManager.shouldKeepHeightCacheWhenReloadingData = YES;
  374. [self.cellAutoHeightManager insertNewDataAtTheBeginingOfSection:section newDataCount:count];
  375. [self reloadData];
  376. }
  377. - (void)reloadDataWithInsertingDataAtTheBeginingOfSections:(NSArray *)sectionNumsArray newDataCounts:(NSArray *)dataCountsArray
  378. {
  379. self.cellAutoHeightManager.shouldKeepHeightCacheWhenReloadingData = YES;
  380. [sectionNumsArray enumerateObjectsUsingBlock:^(NSNumber *num, NSUInteger idx, BOOL *stop) {
  381. int section = [num intValue];
  382. int dataCountForSection = [dataCountsArray[idx] intValue];
  383. [self.cellAutoHeightManager insertNewDataAtTheBeginingOfSection:section newDataCount:dataCountForSection];
  384. }];
  385. [self reloadData];
  386. }
  387. - (CGFloat)cellsTotalHeight
  388. {
  389. CGFloat h = 0;
  390. if (!self.cellAutoHeightManager.heightCacheDict.count) {
  391. [self reloadData];
  392. }
  393. NSArray *values = [self.cellAutoHeightManager.heightCacheDict allValues];
  394. for (NSNumber *number in values) {
  395. h += [number floatValue];
  396. }
  397. return h;
  398. }
  399. - (SDCellAutoHeightManager *)cellAutoHeightManager
  400. {
  401. SDCellAutoHeightManager *cellAutoHeightManager = objc_getAssociatedObject(self, _cmd);
  402. if (!cellAutoHeightManager) {
  403. cellAutoHeightManager = [[SDCellAutoHeightManager alloc] init];
  404. [self setCellAutoHeightManager:cellAutoHeightManager];
  405. }
  406. return cellAutoHeightManager;
  407. }
  408. - (void)setCellAutoHeightManager:(SDCellAutoHeightManager *)cellAutoHeightManager
  409. {
  410. objc_setAssociatedObject(self, @selector(cellAutoHeightManager), cellAutoHeightManager, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
  411. }
  412. - (void)setCellDataSetting:(AutoCellHeightDataSettingBlock)cellDataSetting
  413. {
  414. self.cellAutoHeightManager.cellDataSetting = cellDataSetting;
  415. }
  416. - (AutoCellHeightDataSettingBlock)cellDataSetting
  417. {
  418. return self.cellAutoHeightManager.cellDataSetting;
  419. }
  420. @end
  421. @implementation UITableViewController (SDTableViewControllerAutoCellHeight)
  422. - (CGFloat)cellHeightForIndexPath:(NSIndexPath *)indexPath cellContentViewWidth:(CGFloat)width
  423. {
  424. return [self cellHeightForIndexPath:indexPath cellContentViewWidth:width tableView:self.tableView];
  425. }
  426. @end
  427. @implementation NSObject (SDAnyObjectAutoCellHeight)
  428. - (CGFloat)cellHeightForIndexPath:(NSIndexPath *)indexPath cellContentViewWidth:(CGFloat)width tableView:(UITableView *)tableView
  429. {
  430. tableView.cellAutoHeightManager.modelTableview = tableView;
  431. if (tableView.cellAutoHeightManager.contentViewWidth != width) {
  432. tableView.cellAutoHeightManager.contentViewWidth = width;
  433. }
  434. if ([tableView.cellAutoHeightManager heightCacheForIndexPath:indexPath]) {
  435. return [[tableView.cellAutoHeightManager heightCacheForIndexPath:indexPath] floatValue];
  436. }
  437. UITableViewCell *cell = [tableView.dataSource tableView:tableView cellForRowAtIndexPath:indexPath];
  438. tableView.cellAutoHeightManager.modelCell = cell;
  439. if (cell.contentView.width_sd != width) {
  440. cell.contentView.width_sd = width;
  441. }
  442. return [[tableView cellAutoHeightManager] cellHeightForIndexPath:indexPath model:nil keyPath:nil];
  443. }
  444. @end