<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
我們平時用UITableView
用的很多,所以對列表的優化也是很關注的。很多時候,我們設定UIImageView
,都是比例固定好寬高的,然後通過 scaleAspectFill
和 clipsToBounds
保持圖片不變形,這樣子做開發的效率是很高的,畢竟圖片寬高我們都是固定好的了。
那如果產品要求圖片按真正的比例展示出來呢?如果伺服器有返回寬和高,那就好辦了,那如果沒有呢,我們應該怎麼去做呢?
下面就讓我們一起來探索吧。
一般我們的做法都是用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開發 TableView 網路請求/展示預載入
以上就是ios開發UITableViewCell圖片載入優化詳解的詳細內容,更多關於ios UITableViewCell圖片載入的資料請關注it145.com其它相關文章!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45