在 UICollectionView 中显示错误的图像

Posted

技术标签:

【中文标题】在 UICollectionView 中显示错误的图像【英文标题】:Show wrong images in UICollectionView 【发布时间】:2017-07-24 14:03:10 【问题描述】:

那里!我需要你的帮助。我在 UICollectionView 中有 UIImage,它位于 UITableView 中。当我第一次从 API 获取数据时,它会正确显示图像,但是当我开始向下滚动并返回时,它会显示错误的图像。我的代码如下所示:

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell 
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! AllPostsOfUserCollectionViewCell

    let post = allPostsOfUserArray[collectionView.tag]
    if post.imageLinks.count != 0 
        let imageLink = post.imageLinks[indexPath.row]

        if imageLink.imageLink != nil 
            let url = URL(string: imageLink.imageLink!)

            cell.imageOfAnimalInCollectionView.sd_setImage(with: url!, placeholderImage: UIImage(named: "App-Default"),options: SDWebImageOptions(rawValue: 0), completed:  (image, error, cacheType, imageURL) in
            )
        
    

    return cell

我的模型如下所示:

class UserContent 

var name = ""
var imageLinks = [UserImages]()

init(name: String, imageLinks: [UserImages]?)         
    self.name = name
    if imageLinks != nil 
        self.imageLinks = imageLinks!
    


init()  

deinit 
    imageLinks.removeAll()
  



class UserImages 

var imageLink: String?

init(imageLink: String?) 
    self.imageLink = imageLink


init()  

deinit 
    imageLink = ""
   
 

我在 UITableView 中做什么

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 

    let index = indexPath.row

    let cell = tableView.dequeueReusableCell(withIdentifier: "cell") as! AllPostsOfUserTableViewCell

    cell.collectionView.tag = index

    let post = allPostsOfUserArray[index]
    if post.imageLinks.count == 0 
        cell.collectionView.isHidden = true
     else 
        cell.collectionView.isHidden = false
    

    return cell

UPD: 我将 cell.collectionView.reloadData() 添加到 func tableView(cellForRowAt indexPath)。现在它工作正常。

【问题讨论】:

在您的所有else(您没有这样做)中,您需要删除图像或放置一个占位符。 【参考方案1】:

你能试试这个代码吗:

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell 
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! AllPostsOfUserCollectionViewCell
    cell.imageOfAnimalInCollectionView.image = UIImage(named: "App-Default")
    let post = allPostsOfUserArray[collectionView.tag]
    if post.imageLinks.count != 0 
        let imageLink = post.imageLinks[indexPath.row]

        if imageLink.imageLink != nil 
            let url = URL(string: imageLink.imageLink!)

            cell.imageOfAnimalInCollectionView.sd_setImage(with: url!, placeholderImage: UIImage(named: "App-Default"),options: SDWebImageOptions(rawValue: 0), completed:  (image, error, cacheType, imageURL) in
            )
        
    

    return cell

【讨论】:

【参考方案2】:

这个问题有点像竞态条件。 你可以参考我在similair question的回答

您可能需要找到另一个模块来下载图像并手动设置为单元格。

【讨论】:

【参考方案3】:
cell.imageOfAnimalInCollectionView.image = nil
if post.imageLinks.count != 0 
    let imageLink = post.imageLinks[indexPath.row]

    if imageLink.imageLink != nil 
        let url = URL(string: imageLink.imageLink!)

        cell.imageOfAnimalInCollectionView.sd_setImage(with: url!, placeholderImage: UIImage(named: "App-Default"),options: SDWebImageOptions(rawValue: 0), completed:  (image, error, cacheType, imageURL) in
        )
    


(未测试,但应该可以工作。你也可以使用sd_image的方法分配一个空的url,用一个占位符图像来显示占位符图像。或者只给一个空的url字符串''而不带占位符图片)

每当您滚动时,单元格都会被重新使用,并且分配给单元格的图像会重新出现,因为它仍在单元格上。 您必须使用 else 子句为您将图像分配给 imageView 的每个 if 删除这些图像。

希望这会有所帮助。

【讨论】:

谢谢,不过还是有些麻烦。我想,也许是因为模型不对。 @DmytroRyshchuk 很高兴您找到了解决方案。尽管如此,我认为将图像设置为 nil 或占位符图像是一个好习惯。如果您要处理更多数据,这将很有帮助【参考方案4】:

你必须像下面这样写 else 条件 ..

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell 
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! AllPostsOfUserCollectionViewCell

    let post = allPostsOfUserArray[collectionView.tag]
    if post.imageLinks.count != 0 
        let imageLink = post.imageLinks[indexPath.row]

        if imageLink.imageLink != nil 
            let url = URL(string: imageLink.imageLink!)

            cell.imageOfAnimalInCollectionView.sd_setImage(with: url!, placeholderImage: UIImage(named: "App-Default"),options: SDWebImageOptions(rawValue: 0), completed:  (image, error, cacheType, imageURL) in
            )
        
else 
      cell.imageOfAnimalInCollectionView = "defaultImage"
    
 
else 
     cell.imageOfAnimalInCollectionView = "defaultImage"
    
    return cell

原因 在将单元格出列后,cellectionView 会为所有下一个单元格重用创建的单元格,因此如果您不编写 else 条件或不使用 prepareForReuse 方法,它将始终在其缓存中的前一个单元格的数据。

【讨论】:

以上是关于在 UICollectionView 中显示错误的图像的主要内容,如果未能解决你的问题,请参考以下文章

UICollectionView 在滚动后显示错误的单元格 - 出队问题?

UICollectionView 不显示 - 错误?

UICollectionView 在帧更改后错误地显示单元格

简单的UICollectionView显示图像表现奇怪:某些图像显示正确,有些图像位置错误,有些图像丢失

UICollectionView 给出“索引超出范围”错误

如何在不同的 UICollectionView 单元格中显示不同的视频?