UITableViewCell自適應圖片高度

WenBo丨星空灬發表於2018-01-01

一、問題描述

最近在做公司專案的時候,遇到了前端上傳多張圖片到七牛伺服器後,前端在列表展示圖片適配的問題。一開始我設定的固定高度,因為圖片尺寸不是固定的,會出現不同程度的拉伸情況,使用者體驗也很不好。通過設定圖片檢視contentMode這個屬性,雖然能保證圖片不被拉伸,但圖片會出現顯示不全的問題。

二、解決思路

1、後臺返回每張圖片的寬高,根據比例去計算圖片的高度

2、獲取到image,image有size這個屬性,可以拿到寬高,根據比例去計算圖片的高度

三、最終採用方案

第一種方案是可以實現圖片的適配問題,我採用了第二種。圖片都是網路載入的,要想拿到image,就必須要將圖片下載下來,這樣就可以獲取到圖片的尺寸。下面貼出我實現的關鍵步驟吧。

1、工程匯入SDWebImageMasonry,匯入相關標頭檔案。

2、SDWebImage下載圖片,並計算出圖片高度,將高度快取到字典。自定義cell用Masonry設定好上下左右約束,也可以是xib。

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    ImageViewCell *cell = [tableView dequeueReusableCellWithIdentifier:kIdentifier forIndexPath:indexPath];
    cell.selectionStyle = UITableViewCellSelectionStyleNone;
    NSString *url = self.imageUrlArray[indexPath.row];
    [cell.autoImageView sd_setImageWithURL:[NSURL URLWithString:url] placeholderImage:nil options:SDWebImageRetryFailed completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) {
        if (image.size.height) {
            /**  < 圖片寬度 >  */
            CGFloat imageW = [UIScreen mainScreen].bounds.size.width - 2 * 15;
            /**  <根據比例 計算圖片高度 >  */
            CGFloat ratio = image.size.height / image.size.width;
             /**  < 圖片高度 + 間距 >  */
            CGFloat imageH = ratio * imageW + 15;
            /**  < 快取圖片高度 沒有快取則快取 重新整理indexPath >  */
            if (![[self.heightDict allKeys] containsObject:@(indexPath.row)]) {
                [self.heightDict setObject:@(imageH) forKey:@(indexPath.row)];
                [self.tableView beginUpdates];
                [self.tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationNone];
                [self.tableView endUpdates];
            }
        }
    }];
    return cell;
}
複製程式碼

注意

  • 字典key也可以是圖片地址url
  • 因為圖片下載是非同步的,要在下載完成圖片之後,如果字典沒有快取當前indexPath高度,需要手動去重新整理一次indexPath(最開始的時候,我沒有根據key去判斷是否需要重新整理,當cell滑動的時候,會不停的呼叫cellForRowAtIndexPath這個方法,會不停的重新整理,這樣也非常耗費效能)。

3、cell高度代理方法返回快取的圖片高度

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
    return [[self.heightDict objectForKey:@(indexPath.row)] floatValue];
}
複製程式碼

到這裡,就已經實現了圖片自適應高度的需求了,具體詳情,請看測試UITableViewCellAutoImageHeight。實現這個需求,自己也折騰了一段時間,上面的方法現在也能滿足專案的需求,但是在UI效果上感覺還是有一些不完美之處。如果大神有更好的實現方案和優化方法,希望能多多交流學習。如果以後有更好的實現方案,我也會在這篇文章中記錄下來。

四、結語

2017年還剩兩天,這篇文章也是今年寫的最後一篇文章吧,寫文章的初衷也是為了記錄自己學習成長的點滴,同時也希望能夠幫助到需要的人。2017就要結束了,自己的期望也未達到,希望在即將到來的2018年,自己更加努力,能夠實現自己的期望與目標。奮鬥吧,少年!

相關文章