您好,登錄后才能下訂單哦!
這篇“ios開發UITableViewCell圖片加載優化的方法”文章的知識點大部分人都不太理解,所以小編給大家總結了以下內容,內容詳細,步驟清晰,具有一定的借鑒價值,希望大家閱讀完這篇文章能有所收獲,下面我們一起來看看這篇“ios開發UITableViewCell圖片加載優化的方法”文章吧。
一般我們的做法都是用UITableViewAutomaticDimension
來實現的。
以往的做法,我們都是直接 sd_setImageWithURL
來實現添加圖片,那現在也一樣,我們也是通過這個來獲取圖片寬和高。
- (void)sd_setImageWithURL:(nullable NSURL *)url placeholderImage:(nullable UIImage *)placeholder completed:(nullable SDExternalCompletionBlock)completedBlock
完成后,我們可以拿到UIImage
,從而知道圖片的 size
。然后我們就可以按比例來獲取圖片的高度,再通過更新約束來改變圖片高度。
大概做法如下:
[_imageView sd_setImageWithURL:[NSURL URLWithString:model.urlStr] completed:^(UIImage * _Nullable image, NSError * _Nullable error, SDImageCacheType cacheType, NSURL _Nullable imageURL) { if (image) { // 獲取圖片寬高 CGSize imageSize = image.size; CGFloat maxWidth = kSCREEN_WIDTH - 32; // 按比例獲取當前的高度 CGFloat height = imageSize.height * maxWidth / imageSize.width; [self.imageView mas_updateConstraints:^(MASConstraintMaker *make) { make.height.mas_equalTo(height); }]; } }];
然后我們一運行代碼,發現圖片的高度并沒有展示我們想要的高度,可以說是連高度都沒有。
很明顯是圖片的高度沒有生效。想想也是,我們是異步調用加載圖片的,這時候等異步結果回來調用mas_updateConstraints
,并不會觸發代理 heightForRowAtIndexPath
,那怎么會更新高度呢。
既然是這樣,那我們就重新加載該列表吧。
[cell setHeightBlock:^(CGFloat imageHeight){ [tableView beginUpdates]; [tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationNone]; [tableView endUpdates]; }];
我們更新完mas_updateConstraints
后,這時候,直接刷新該列表,就可以解決問題了。
這時候我們重新運行,效果還可以,但在來回滾動的時候,發現有點卡。很明顯,我們滾動的時候每次都要重新刷新cell
。
如果我們有緩存了,那就知道了圖片的高度,那我們是不是就不需要reloadRowsAtIndexPaths
。
所以我再次進行優化
// 是否有緩存 BOOL hasCache = [[SDImageCache sharedImageCache] diskImageDataExistsWithKey:model.urlStr]; [_ImageView sd_setImageWithURL:[NSURL URLWithString:model.urlStr] completed:^(UIImage * _Nullable image, NSError * _Nullable error, SDImageCacheType cacheType, NSURL * _Nullable imageURL) { if (image) { CGSize imageSize = image.size; CGFloat maxWidth = kSCREEN_WIDTH - 32; CGFloat height = imageSize.height * maxWidth / imageSize.width; [self.imageView mas_updateConstraints:^(MASConstraintMaker *make) { make.height.mas_equalTo(height); }]; // 有緩存就不去reloadRowsAtIndexPaths if (!hasCache && self.heightBlock) { self.heightBlock(height); } } }];
如果發現是有緩存圖片了,我們就不刷新列表了。sd_setImageWithURL
這時候也是從緩存里面讀取圖片,就不是異步加載了,所以不用再次刷新了當前cell
了。
有的人說,這么寫好像挺麻煩的,有沒有封裝好的寫法,的確有的。
那就是第三方庫 XHWebImageAutoSize,它的寫法其實也是用了 SDWebImage
來進行優化操作的。
[_imageView sd_setImageWithURL:[NSURL URLWithString:model.urlStr] completed:^(UIImage * _Nullable image, NSError * _Nullable error, SDImageCacheType cacheType, NSURL * _Nullable imageURL) { if (image) { /** 緩存image size */ [XHWebImageAutoSize storeImageSize:image forURL:imageURL completed:^(BOOL result) { /** reload */ if(result && self.heightBlock) { self.heightBlock(0) } ]; } }];
緩存圖片后,一樣是去刷新cell。
[cell setHeightBlock:^(CGFloat imageHeight) { [tableView xh_reloadDataForURL:[NSURL URLWithString:model.urlStr]]; }];
然后就是重新加載高度。
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { ImageModel *model = _dataArray[indexPath.row]; return [XHWebImageAutoSize imageHeightForURL:[NSURL URLWithString:model.urlStr] layoutWidth:[UIScreen mainScreen].bounds.size.width-32 estimateHeight:200] + 50; }
后面加的 50
是其他的高度,例如cell
里面還有title
,就是圖片+其他高度。
這樣也能實現圖片自適應高度。
圖片列表實在太多了,一直滑滑滑,圖片加載速度跟不上手速啊,感覺有點卡,我們可以僅加載當前屏幕的內容。滑動的時候,我們不加載,等列表停后,我們再次加載當前屏幕的內容。
這時候我們在模型model
里面,添加一個isLoad
的參數,如果是true
,我們才加載。
先添加一個當前屏幕加載cell
的方法。
-(void)loadCurrentCells{ NSArray * array = [self.tableView indexPathsForVisibleRows]; for (NSIndexPath *indexPath in array) { JJTableViewCell * cell = (JJTableViewCell *)[self.tableView cellForRowAtIndexPath:indexPath]; ImageModel *model = _dataArray[indexPath.row]; //設置為可以加載 model.isLoad = YES; //配置cell [cell configCellWithImageModel:model]; } }
cell
里面對model
的isLoad
進行判斷。
- (void)configCellWithImageModel:(ImageModel *)model { if (model.isLoad) { [_imageView sd_setImageWithURL:[NSURL URLWithString:model.urlStr]]; }else { _imageView.image = [UIImage imageNamed:@"default_images_icon"]; } }
如果暫不加載,我們可以先設置占用圖片。
這樣一來,我們只要監聽停止滑動的時候,我們就設置加載當前頁面的內容即可。
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate { if (!decelerate) { [self loadCurrentCells]; } } - (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView { [self loadCurrentCells]; }
當然一開始我們reloaData
的時候,所有isload
都為false
,所以我們需要加載一次當前cell
內容。
[self.tableView reloadData]; [self loadCurrentCells];
這樣,我們就可以做到一直滑動的時候,不異步加載圖片,等滑動停止再加載當前屏幕的圖片。
當然除了這種寫法,我們還可以通過RunLoop
來實現。
所謂預加載,就是一直滑動,我們翻頁的時候,提前加載數據出來,讓用戶的感覺就是一直有數據。就沒有出現上拉加載更多
這種情況。
總體思路是:當滑動距離占比到了總滑動距離的時候的%90
(不固定),就觸發預加載。
以上就是關于“ios開發UITableViewCell圖片加載優化的方法”這篇文章的內容,相信大家都有了一定的了解,希望小編分享的內容對大家有幫助,若想了解更多相關的知識內容,請關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。