collectionView 中的图像在滚动时发生变化

Posted

技术标签:

【中文标题】collectionView 中的图像在滚动时发生变化【英文标题】:Images in the collectionView are changing while scrolling 【发布时间】:2017-06-12 16:55:17 【问题描述】:

我正在使用 xcode 8.3。我有一个 CollectionView。我已经从网络服务下载了图像并将图像放置在每个 CollectionView 单元格中。但是当我滚动 CollectionView 时,每个单元格中的图像都在变化。几分钟后,它显示正确的图像。我已经尝试了许多 *** 中可用的解决方案。但我没有得到解决方案。请帮我。

【问题讨论】:

请编辑您的问题,以包括您编写的从 Web 服务加载图像的代码,以及您编写的将图像放入单元格中的代码。 尝试 sdwebimage 进行图片下载.. 【参考方案1】:

就像其他人所说的那样,这很可能是因为您正在使可重复使用的单元格出列(应该如此)并将 cell.imageView.image 属性设置为您的网络图像。

这里的问题是,因为 ios 通过“重用”这些单元格来节省内存,所以它们实际上是内存中的相同单元格。因此,当它从屏幕的一个边缘滚动并消失时。随着新单元格滚动而不是创建一个新的单独单元格,它只是使用它已经拥有的刚刚离开屏幕的单元格。这意味着您的旧图像仍然是单元格中显示的图像。

标准做法是在cellForRowAtIndexPath: 方法中设置单元格的内容。但是,如果您将其设置为异步获取的图像,则单元格完全有可能(很可能)在获取新图像之前与旧图像一起出现在屏幕上。据推测,一旦图像被下载,它就不再是什么问题了,因为它们应该立即从缓存中返回。

这里的简单解决方法是在每次在单元格中设置图像之前将图像清零,或者最好使用占位符图像。

-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath 
    MyCustomCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"CELL_IDENTIFIER" forIndexPath:indexPath];

    // This will clear any existing image from the cell about to be displayed it is an option
    //[cell.imageView setImage:nil];

    if (ImageExistsLocally)
    
        cell.imageView.image = [UIImage imageWithContentsOfFile:@"SomeImagePath"];
     
    else 
    
        [cell.cellImageView sd_setImageWithURL:yourRemoteImage.thumbnailUrl
                              placeholderImage:[UIImage imageNamed:PlaceHolderImageName]
                                     completed:nil];
    
    return cell;

请注意,sd_setImageWithURL 来自我认为其他人在这里提到的 SDWebImage 库。 https://cocoapods.org/pods/SDWebImage

【讨论】:

【参考方案2】:

这是因为重复使用单元格。尝试在您的单元格类 prepareForReuse 方法中重置图像

-(void)prepareForReuse 
    [super prepareForReuse];
    self.imageView.image = nil;

【讨论】:

【参考方案3】:

您面临的问题是由于 UITableViewCell 的重用。 如果您从 Web 服务下载图像,请使用 AlamofireImage 或 SDWebImage。它会解决你的问题。

【讨论】:

【参考方案4】:

UICollectionView 重复使用相同的UICollectionViewCell 来提高性能。只有UICollectionViewCell里面的数据被改变了,所以在使用UICollectionViewCell之前,UICollectionViewCell之前的数据必须被清除。 Cocoa Framework 提供了一种存在于 UICollectionViewCell 中的方法,该方法在每次要重用 UICollectionViewCell 时触发。

只需在您的自定义UICollectionViewCell 类文件的.m 文件中覆盖下面给出的函数

-(void)prepareForReuse 
    [super prepareForReuse];
// here we clear the previously set data
    self.imageView.image = nil; // this will clear the previously set imageView is a property of UIImageView used to display a image data

【讨论】:

【参考方案5】:

您可以使用prepareForReuse() 方法来处理这个问题。

override func prepareForReuse() 
    super.prepareForReuse()

    // still visible on screen (window's view hierarchy)
    if self.window != nil  return 

    imageView.image = nil

注意事项:如果您使用的是 SDWebImage,则应添加此行以取消当前单元格图像下载。

imageView.sd_cancelCurrentAnimationImagesLoad()

【讨论】:

以上是关于collectionView 中的图像在滚动时发生变化的主要内容,如果未能解决你的问题,请参考以下文章

如何在不重新加载图像的情况下重新加载 collectionview 单元格

滚动时collectionview更改单元格背景图像

ios - 使用图像水平滚动collectionView

在快速滚动collectionview时,第一行数据在最后一行重复

Collectionview 图像单元格滚动问题

识别 CollectionView 中的单元格