SDWebImage + UITableViewCell,滚动时图像错误?

我有一个问题,使用SDWebImage加载图像到自定义UITableViewCell内的UIImageView。 这是我在UITableView委托的代码:

static NSString *userTableId = @"userTableId"; UserDetailsTableViewCell *cell = (UserDetailsTableViewCell *)[tableView dequeueReusableCellWithIdentifier:userTableId]; NSDictionary *user = [userList objectAtIndex:indexPath.row]; NSInteger position = indexPath.row + 1; [cell.userDetailsView loadFromDictionary:user WithIndex:position ForCharitie:false]; cell.userDetailsView.delegate = self; cell.userDetailsView.delegate = self; return cell; 

这里是我的代码为loadFromDictionary:

 -(void) loadFromDictionary: (NSDictionary *) dic WithIndex: (NSInteger) index ForCharitie: (BOOL) isCharitie{ NSDictionary *userImageDic = [dic objectForKey:@"image"]; NSString *url =[userImageDic objectForKey:@"url"]; [userImage setImage:[UIImage imageNamed:@"defaultAvatar"]]; if ([url class] != [NSNull class]){ [userImage setImageWithURL:[NSURL URLWithString:url] placeholderImage:[UIImage imageNamed:@"defaultAvatar"]]; } } 

现在,问题是如果我在一些图像完成加载之前向下滚动。 例如,假设我看到前8行,第1,2和3行仍在加载它们的图像,现在我滚动到9-16,我看到了所有这些的defaultAvatar ,几秒钟后(我猜是什么时候行1,2和3的图像完成下载),单元格9,10和11上的图像更改为属于1,2和3的图像。我不知道是否有方法来阻止图像下载当我重新使用这个单元格,或类似的东西。 谢谢你,对不起我的英文!

如果你在你的表上设置了你的UITableViewDelegate,你可以使用委托方法:

- tableView:didEndDisplayingCell:forRowAtIndexPath:

当您的单元格滚动屏幕时将图像设置为NULL(或默认)。

而且由于您使用的是SDWebImage,取消它可能就像在单元格的图像视图中的“ cancelCurrentImageLoad ”一样简单。

在你的单元类中重写prepareForReuse方法,并取消所有的加载。 别忘了叫super

上面的答案的例子。 Swift 3

 func collectionView(_ collectionView: UICollectionView, didEndDisplaying cell: UICollectionViewCell, forItemAt indexPath: IndexPath) { (cell as! UITableViewCell).imageView.image = nil (cell as! UITableViewCell).imageView.sd_cancelCurrentImageLoad() } 

我用被接受的答案得到空白的图像,并且由于我正在加载的图像很小,我想让图像caching在后台,而不是取消加载。

  1. 在closures之前在堆栈上推送一个唯一的ID,并在closures完成时检查它
  2. prepareForReuse

喜欢这个:

 func updateArtistImage(url: URL) { let _eventId = self.event?.id SDWebImageManager.shared().loadImage(with: url, options: [], progress: nil) { (image, data, error, cacheType, finished, url) in if self.event!.id == _eventId { if error == nil { self.artistImageView.image = image } else { self.artistImageView.image = UIImage(named: "error_image") } } } } 

和这个:

 override func prepareForReuse() { super.prepareForReuse() self.artistImageView.image = nil } 

在调用sd_cancelCurrentImageLoad ,只需调用sd_cancelCurrentImageLoad并设置[imageView setImage:nil] sd_cancelCurrentImageLoad [imageView setImage:nil]

 [imageView sd_cancelCurrentImageLoad];