填充collectionView单元格图像时从Firebase加载错误的照片并非每次都发生

Posted

技术标签:

【中文标题】填充collectionView单元格图像时从Firebase加载错误的照片并非每次都发生【英文标题】:Load wrong photos from Firebase when fill collectionView cells image not happen everytime 【发布时间】:2018-01-29 15:19:59 【问题描述】:

我想知道这是否是我的代码的问题,因为从 Firebase(Firebase 中的 URL)加载的图像几乎有一半时间没有显示来自 Firebase 的正确照片。 我向您展示我的 collectionView 中的两个屏幕截图: - 这个案例中的第一个是加载了正确的照片:(在这种情况下没有错误),这是我每次都想显示的内容

第二个,如果我重新加载视图我可以看到这张图片,在这种情况下你可以看到两张照片是双倍的,但正确的照片应该像第一张图片一样(Firebase 不会从存储)

如果我再次重新加载,此问题可能会再次出现或在正确的位置显示正确的照片。 所以我不知道为什么会出现这个问题。

这里你可以看到我的collectionView的cellRowItemAt函数的代码:

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell 
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! CollectionViewCell
    let photoLive = liveRecent[indexPath.row].photoURL

    self.storageRef.reference(forURL: photoLive!).getData(maxSize: 1 * 1024 * 1024)  (imgData, error) in
        if let error = error 
            let alertView = UIAlertView(title: "Error", message: error.localizedDescription, delegate: nil, cancelButtonTitle: "OK")
            alertView.show()
         else 
            DispatchQueue.main.async(execute: 
                if let data = imgData 
                    cell.imageViewUn.image = UIImage(data: data)
                
            )
            DispatchQueue.main.async 
                cell.imageViewUn.reloadInputViews()
            
        
    
    return cell

我的代码有什么问题? 感谢您的帮助。

编辑:prepareForReuse() 函数中应该写什么:

class CollectionViewCell: UICollectionViewCell 

@IBOutlet weak var imageViewUn: UIImageView!
var downloadTask: StorageDownloadTask!

public override func prepareForReuse() 
    super.prepareForReuse()
    self.imageViewUn.image = nil

    downloadTask.cancel()


【问题讨论】:

【参考方案1】:

这个问题很可能发生,因为您的集合视图单元格中的图像设置与该单元格的生命周期分离。当您在单元格中设置图像时,您不知道该单元格是否仍然有效,或者它是否已被另一个单元格重复使用。您需要能够在重复使用单元格时取消图像加载,或者将单元格索引存储在单元格中,并且在加载图像后检查索引是否已更改。

一个有用的函数可以用来捕捉一个单元格被重用的时候

UICollectionReusable.prepareForReuse().

在您的单元格类中覆盖它并添加代码以取消您的图像加载或以某种方式使其无效。

【讨论】:

好的,谢谢,我会试试的。你认为 UITableView 有同样的功能吗?因为我认为 tableView 需要同样的东西 UITableViewCell 有一个 prepareForReuse() 函数 我应该在我的单元类的 prepareForReuse() 函数中写什么来取消加载图像或使其无效?因为我尝试了“isHidden”属性但同样的问题。你能给我一些建议吗? 我用我的自定义类更新了我的答案,但出现了一个致命错误,因为我从超级视图中删除了 imageView,所以也许我应该在重新加载图像函数时准备好它?如何做到这一点 我猜如果您在单元格中保留了存储下载任务的句柄,您可以在 prepareForReuse() 中取消下载。我对 Firebase 没有丰富的经验,所以不能确定。不要删除 UIImageView

以上是关于填充collectionView单元格图像时从Firebase加载错误的照片并非每次都发生的主要内容,如果未能解决你的问题,请参考以下文章

在自定义 collectionview 单元格中填充图像而不会闪烁

点击时从 UICollectionView 中的单元格获取图像

裁剪 UIImagePicker 并输出到 CollectionView 单元格

CollectionView 并不总是正确显示数据

在不同的collectionView单元格中填充不同的tableViews

从popover返回后如何在collectionview单元格中填充文本字段