你好,歡迎來到IOS教程網

 Ios教程網 >> IOS編程開發 >> IOS編程技術 >> iOS開發之計算動態cell的高度並緩存

iOS開發之計算動態cell的高度並緩存

編輯:IOS編程技術

項目中有個類似微博那樣的動態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的文章

  1. 上一頁:
  2. 下一頁:
蘋果刷機越獄教程| IOS教程問題解答| IOS技巧綜合| IOS7技巧| IOS8教程
Copyright © Ios教程網 All Rights Reserved