根據(jù)圖片動(dòng)態(tài)計(jì)算UITableViewCell的高度

本文參考http://www.tuicool.com/articles/iMNrAf 進(jìn)行了整理

使用場(chǎng)景

UITableViewCell需要加載來(lái)自服務(wù)器的圖片细诸,cell的寬度一定,高度需要根據(jù)加載的圖片動(dòng)態(tài)調(diào)整微王。

難點(diǎn)

需要顯示的圖片來(lái)自服務(wù)器,只有圖片加載完成以后才能知道圖片的高度贾铝。

解決方法

1.圖片異步加載完成以后更新cell的height嘉抓,刷新tableview。
2.采用SDWebImage緩存已經(jīng)加載過(guò)的圖片胜茧。
3.在tableview處于滑動(dòng)狀態(tài)時(shí)不加載圖片,不刷新tableview仇味,tableview停止滑動(dòng)時(shí)觸發(fā)reloadData呻顽。
4.添加清空緩存空能,防止app占用太多的磁盤空間邪铲。

代碼

//_cellHeights:保存所有cell高度的數(shù)組
//deatilContents:tableview的數(shù)據(jù)源
//配置cell
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    NSString *imageIdentifier = [NSString stringWithFormat:@"imageIdentifier_%ld",(long)indexPath.row];
    DetailImageCell *imageCell = [tableView dequeueReusableCellWithIdentifier:imageIdentifier];
    if (!imageCell) {
        imageCell = [[DetailImageCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:imageIdentifier];
    }

    [self configureCell:imageCell atIndexPath:indexPath];
    return imageCell;
}

//根據(jù)獲取的image高度設(shè)置cell高度芬位,如果圖片還沒(méi)有加載成功,就先設(shè)置為默認(rèn)圖片带到,所有cell的高度都存在數(shù)組_cellHeights中
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {

    NSDictionary *dict = [deatilContents safeObjectAtIndex:indexPath.row];
    UIImage *img = [[SDImageCache sharedImageCache] imageFromDiskCacheForKey:[dict safeObjectForKey:@"photoUrl"]];
    if (!img) {
        img = [UIImage imageNamed:@"placeholder"];
    }
    CGFloat height = [DetailImageCell cellHeightWithImage:img];
    [_cellHeights replaceObjectAtIndex:indexPath.row withObject:[NSString stringWithFormat:@"%f",height]];

    return [[_cellHeights safeObjectAtIndex:indexPath.row] floatValue];
}

//pragma mark 設(shè)置帶有圖片的cell
-(void)configureCell:(DetailImageCell *)cell atIndexPath:(NSIndexPath *)indexPath
{
    NSDictionary *dict = [deatilContents safeObjectAtIndex:indexPath.row];
    NSString *imgURL = [dict safeObjectForKey:@"photoUrl"];
    UIImage *cachedImage = [[SDImageCache sharedImageCache] imageFromDiskCacheForKey:imgURL];

    if ( !cachedImage ) {
        //如果tableview正在滾動(dòng)/滑動(dòng)就先不加載圖片昧碉,只有處于靜止?fàn)顟B(tài)時(shí)才開(kāi)始加載
        if ( !self.tableView.dragging && !self.tableView.decelerating ) {
            [self downloadImage:imgURL forIndexPath:indexPath];
        }
        //在圖片沒(méi)有加載完成之前英染,先用默認(rèn)圖片替代
        [cell setImage:[UIImage imageNamed:@"placeholder"] withHeight:[[_cellHeights safeObjectAtIndex:indexPath.row] floatValue]];
    } else {
      //緩存中拿到了需要加載的圖片直接顯示真實(shí)圖片
        [cell setImage:cachedImage withHeight:[[_cellHeights safeObjectAtIndex:indexPath.row] floatValue]];
    }
}

//根據(jù)路徑加載圖片,加載完成后進(jìn)行緩存被饿,并刷新tableview
- (void)downloadImage:(NSString *)imageURL forIndexPath:(NSIndexPath *)indexPath
{
    weakSelf(weakSelf)
    [[SDWebImageDownloader sharedDownloader] downloadImageWithURL:[NSURL URLWithString:imageURL]
                                                          options:SDWebImageDownloaderUseNSURLCache
                                                        progress:nil
                                                        completed:^(UIImage *image, NSData *data, NSError *error, BOOL finished)
    {
        [[SDImageCache sharedImageCache] storeImage:image forKey:imageURL toDisk:YES];
        [weakSelf performSelectorOnMainThread:@selector(reloadCellAtIndexPath:)
                                withObject:indexPath waitUntilDone:NO];
    }];
}

//pragma mark - Scroll view delegate
// table view 停止拖動(dòng)了四康,刷新tableview開(kāi)始更新
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
{
    if (!decelerate) {
        [self loadImageForOnScreenRows];
    }
}

// table view 停止?jié)L動(dòng)了
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
    [self loadImageForOnScreenRows];
}

//節(jié)約性能,只加載當(dāng)前顯示在屏幕上的cell包含的image
- (void)loadImageForOnScreenRows
{
    NSArray *visiableIndexPathes = [self.tableView indexPathsForVisibleRows];

    for(NSInteger i = 0; i < [visiableIndexPathes count]; i++)
    {
        NSDictionary *dict = [deatilContents safeObjectAtIndex:i];
        NSString *imgURL = [dict safeObjectForKey:@"photoUrl"];
        if (imgURL) {
            [self downloadImage:imgURL forIndexPath:visiableIndexPathes[i]];
        }
    }
}

// 但是別認(rèn)為調(diào)用 table view 的 reloadData 效率就不高狭握,回顧下上面的步驟
// reloadData 實(shí)際上就是向代理要行數(shù)闪金,要行高,對(duì)**顯示出來(lái)**的 cell 填充數(shù)據(jù)
-(void)reloadCellAtIndexPath:(NSIndexPath *)indexpath
{
    [self.tableView reloadData];
}

//這個(gè)函數(shù)在需要清空磁盤的地方調(diào)用论颅,一般都是類似于“我的”頁(yè)面
-(void)clearDiskCache
{
   //獲取當(dāng)前磁盤緩存的大小
    self.cacheStr=[NSString stringWithFormat:@"%.2fM",[[SDImageCache sharedImageCache] getSize]/1024.0/1024.0];
    [[SDImageCache sharedImageCache] clearDisk];
}


最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末哎垦,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子恃疯,更是在濱河造成了極大的恐慌漏设,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,743評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件今妄,死亡現(xiàn)場(chǎng)離奇詭異郑口,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)盾鳞,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,296評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門犬性,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人腾仅,你說(shuō)我怎么就攤上這事乒裆。” “怎么了推励?”我有些...
    開(kāi)封第一講書(shū)人閱讀 157,285評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵缸兔,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我吹艇,道長(zhǎng),這世上最難降的妖魔是什么昂拂? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,485評(píng)論 1 283
  • 正文 為了忘掉前任受神,我火速辦了婚禮,結(jié)果婚禮上格侯,老公的妹妹穿的比我還像新娘鼻听。我一直安慰自己,他們只是感情好联四,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,581評(píng)論 6 386
  • 文/花漫 我一把揭開(kāi)白布撑碴。 她就那樣靜靜地躺著,像睡著了一般朝墩。 火紅的嫁衣襯著肌膚如雪醉拓。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 49,821評(píng)論 1 290
  • 那天,我揣著相機(jī)與錄音亿卤,去河邊找鬼愤兵。 笑死,一個(gè)胖子當(dāng)著我的面吹牛排吴,可吹牛的內(nèi)容都是我干的秆乳。 我是一名探鬼主播,決...
    沈念sama閱讀 38,960評(píng)論 3 408
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼钻哩,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼屹堰!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起街氢,我...
    開(kāi)封第一講書(shū)人閱讀 37,719評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤扯键,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后阳仔,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體忧陪,經(jīng)...
    沈念sama閱讀 44,186評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,516評(píng)論 2 327
  • 正文 我和宋清朗相戀三年近范,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了嘶摊。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,650評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡评矩,死狀恐怖叶堆,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情斥杜,我是刑警寧澤虱颗,帶...
    沈念sama閱讀 34,329評(píng)論 4 330
  • 正文 年R本政府宣布,位于F島的核電站蔗喂,受9級(jí)特大地震影響忘渔,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜缰儿,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,936評(píng)論 3 313
  • 文/蒙蒙 一畦粮、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧乖阵,春花似錦宣赔、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,757評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至对蒲,卻和暖如春钩蚊,著一層夾襖步出監(jiān)牢的瞬間贡翘,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,991評(píng)論 1 266
  • 我被黑心中介騙來(lái)泰國(guó)打工两疚, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留床估,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,370評(píng)論 2 360
  • 正文 我出身青樓诱渤,卻偏偏與公主長(zhǎng)得像丐巫,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子勺美,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,527評(píng)論 2 349

推薦閱讀更多精彩內(nèi)容