一、問題描述
最近在做公司專案的時候,遇到了前端上傳多張圖片到七牛伺服器後,前端在列表展示圖片適配的問題。一開始我設定的固定高度,因為圖片尺寸不是固定的,會出現不同程度的拉伸情況,使用者體驗也很不好。通過設定圖片檢視contentMode這個屬性,雖然能保證圖片不被拉伸,但圖片會出現顯示不全的問題。
二、解決思路
1、後臺返回每張圖片的寬高,根據比例去計算圖片的高度
2、獲取到image,image有size這個屬性,可以拿到寬高,根據比例去計算圖片的高度
三、最終採用方案
第一種方案是可以實現圖片的適配問題,我採用了第二種。圖片都是網路載入的,要想拿到image,就必須要將圖片下載下來,這樣就可以獲取到圖片的尺寸。下面貼出我實現的關鍵步驟吧。
1、工程匯入SDWebImage和Masonry,匯入相關標頭檔案。
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年,自己更加努力,能夠實現自己的期望與目標。奮鬥吧,少年!