简体   繁体   English

UICollectionView + SDWebImage + 单元重用

[英]UICollectionView + SDWebImage + Cell reuse

I have a UICollectionView with a custom UICollectionViewCell class which adds another UIView (thumbnailView) to its contentView.我有一个带有自定义 UICollectionViewCell class 的 UICollectionView,它将另一个 UIView (thumbnailView) 添加到它的 contentView。 This other view has a UIImageView property (imageView) whose image gets loaded with SDWebImage asynchronously.另一个视图有一个 UIImageView 属性 (imageView),其图像通过 SDWebImage 异步加载。 This all works fine until the cell is reused while the image of the original cell is still being loaded.这一切工作正常,直到单元格被重新使用,而原始单元格的图像仍在加载。 If you scroll fast enough through the CollectionView images start to pop up in cells where they are not supposed to be (probably because the cell got reused and the image download finishes afterwards), just to get replaced as soon as the correct image for the reused cell finishes loading.如果您在 CollectionView 中滚动得足够快,图像开始在它们不应该出现的单元格中弹出(可能是因为单元格被重复使用并且图像下载随后完成),只是为了重新使用的正确图像尽快被替换单元格完成加载。

To fix this, I added the following to my UICollectionViewCell subclass to stop the original cell's image download:为了解决这个问题,我将以下内容添加到我的 UICollectionViewCell 子类中以停止原始单元格的图像下载:

- (void)prepareForReuse
{
    [super prepareForReuse];
    [self.thumbnailView.imageView cancelCurrentImageLoad];
}

But to my surprise, this seems to change absolutely nothing.但令我惊讶的是,这似乎完全没有改变。 Am I doing something wrong or am I just looking in the wrong direction?我做错了什么还是我只是看错了方向?

If I understand your problem correctly, you are getting old images still appearing in reused cells so in addition to stopping the previous image load you probably want to remove the old image from the imageView. 如果我正确理解了您的问题,那么您仍然会在重复使用的单元格中显示旧图像,因此除了停止先前的图像加载之外,您可能还想从imageView中删除旧图像。 SDImageView might have a method to clear the image or else you could just manually replace it with a placeholder image. SDImageView可能有清除图像的方法,否则您只需用占位符图像手动替换它。

- (void)prepareForReuse
{
    [super prepareForReuse];
    [self.thumbnailView.imageView cancelCurrentImageLoad];
    [self.thumbnailView.imageView setImage:<<LOCAL PLACEHOLDER IMAGE>> forState:UIControlStateNormal];
}

The UITableViewDelegate and UICollectionViewDelegate method -tableView:didEndDisplayingCell:forRowAtIndexPath: is the best place to update your UITableView | UITableViewDelegateUICollectionViewDelegate方法-tableView:didEndDisplayingCell:forRowAtIndexPath:是更新UITableView的最佳位置。 UICollectionView cells after it has disappeared. UICollectionView单元格消失后。 You can cancel the cell downloads there. 您可以在那里取消单元格下载。

Swift 4 - Add to your cell's class: Swift 4 - 添加到您的手机类:

override func prepareForReuse() {
  super.prepareForReuse() 
  self.contentImageView.sd_cancelCurrentImageLoad()
  self.contentImageView.image = UIImage(named: "") // set to default/placeholder image
}

I tried both didEndDisplayCell() and prepareForReuse(), neither of them work. 我尝试了didEndDisplayCell()和prepareForReuse(),它们都不起作用。 A work round way is to set imageView.image as nil then assign to the specific image, then it will not blink the old image as background. 一种工作方式是将imageView.image设置为nil然后分配给特定图像,然后它不会将旧图像作为背景闪烁。 (but it will be slower since it has to do the "clean" job first). (但它会慢一点,因为它必须先做“干净”的工作)。

SWIFT 4 SWIFT 4

Before setting new image to imageView add: 在将新图像设置为imageView之前添加:

cell.imageView.sd_currentDownloadTask?.cancel()

Eventually, I solve the problem by using static cells programmatically & download images by SDWebImage separately, try to handle the image from cache from another manager.最终,我通过以编程方式使用 static 单元并通过 SDWebImage 单独下载图像来解决问题,尝试从另一个管理器的缓存中处理图像。

here's the SDWebImage code.这是 SDWebImage 代码。

 [imageView sd_internalSetImageWithURL:url placeholderImage:nil options:SDWebImageRetryFailed context:nil setImageBlock:^(UIImage * _Nullable image, NSData * _Nullable imageData, SDImageCacheType cacheType, NSURL * _Nullable imageURL) {
    
 } progress:^(NSInteger receivedSize, NSInteger expectedSize, NSURL * _Nullable targetURL) {
    
 } completed:^(UIImage * _Nullable image, NSData * _Nullable data, NSError * _Nullable error, SDImageCacheType cacheType, BOOL finished, NSURL * _Nullable imageURL) {
    
    if (image) { imageView.image = image; }
    
 }];

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM