如何在重新加载时清除 UICollectionViewCell?

Posted

技术标签:

【中文标题】如何在重新加载时清除 UICollectionViewCell?【英文标题】:How to clear a UICollectionViewCell on reload? 【发布时间】:2017-08-29 07:45:36 【问题描述】:

我遇到了一个问题,UICollectionView 中显示的数据覆盖了标签,并且单元格视图没有被清除。

这张图片显示了问题,

IE:

我的 UICollectionViewCell 是这样构造的;

// in viewDidLoad
self.playerHUDCollectionView.register(UICollectionViewCell.self, forCellWithReuseIdentifier:reuseIdentifer)

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell 
    let cell:UICollectionViewCell = collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifer, for: indexPath) as UICollectionViewCell
    let arr = UINib(nibName: "EYPlayerHUDView", bundle: nil).instantiate(withOwner: nil, options: nil)
    let view = arr[0] as! EYPlayerHUDView
    cell.contentView.addSubview(view)
    if let allPlayers = self.allPlayers
    
        let player:EYPlayer = allPlayers[indexPath.row]
        view.updatePlayerHUD(player: player)
    
    cell.layoutIfNeeded()
    return cell

我使用视图在单元格中显示。

我尝试删除cellForItemAt 中的所有单元格子子项,但它似乎删除了所有子视图。

我想知道如何清除UICollectionViewCell,以便UICollectionViewCell 上的标签和其他信息不会像上面的示例那样脏。

非常感谢

【问题讨论】:

答案在这里:***.com/questions/33940252/… 您的回答有帮助。虽然代码在 Objective C 中;我能够根据我的要求修改和更新它! 在您的自定义单元格类中覆盖 prepareForResure 方法并添加所需的清理。 但是没有自定义单元格类。考虑;集合视图单元格是空的,除了添加子视图之外什么都不做。 【参考方案1】:
//cell = UICollectionViewCell
for subview in cell.contentView.subviews 
     // you can place "if" condition to remove image view, labels, etc.
     //it will remove subviews of cell's content view
     subview.removeFromSuperview()

【讨论】:

【参考方案2】:

在您的自定义单元类中使用prepareForReuse 方法,如下所示:

override func prepareForReuse() 
    super.prepareForReuse()
    //hide or reset anything you want hereafter, for example
    label.isHidden = true

在您的 cellForItemAtIndexPath 中,实例化您的自定义单元格:

let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "myCellIdentifier", for: indexPath) as! CustomViewCell

然后,始终在cellForItemAtIndexPath 中设置您的项目可见性/值

【讨论】:

我应该把prepareForReuse放在什么文件里?如果我把它放在我的 UICollectionViewController 中,它会抱怨该函数不会覆盖超类中的任何方法。没有CustomViewCell;它只是一个标准的 UICollectionViewCell 你应该创建一个 CustomCell 例如:class MyCustomCell: UICollectionViewCell。当您为 CollectionViews 和 TableViews 创建单元格时,这是最好的方法。当然,这取决于您想要定制多少单元格。看到这个tutorial 它有效。非常感谢。接受了你的回答。我删除了 prepareForReuse 函数中所需的子视图 完美!很高兴它对您有所帮助!【参考方案3】:

UICollectionViewCells 被重用以避免实例化,以优化性能。如果您正在滚动并且某个单元格变得不可见,则会再次使用相同的对象 (dequeueReusableCell) 并在 cellForItemAt...

中设置一个新的 content

正如前面的答案中提到的,在重用单元格之前,在单元格上调用prepareForReuse()。所以你可以覆盖prepareForReuse() 并做任何你需要做的准备。

但是,您在每次重复使用时都会创建一个新的 EYPlayerHUDView 并将其添加到单元格中,因此您的单元格会充满堆叠的 EYPlayerHUDViews。

为避免这种情况,将UICollectionViewCell 子类化并将EYPlayerHUDView 设为自定义单元格的属性(我建议使用XIB):

class MyCell: UICollectionViewCell 
    @IBOutlet var player:EYPlayerHUDView!

    override func prepareForReuse() 
        super.prepareForReuse()
        // stop your player here
        // set your label text = ""
    

这样做之后,您可以更新cellForItemAt 中的EYPlayerHUDView,而无需实例化它,也无需将其添加为新视图:

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell 
    guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifer, for: indexPath) as? MyCell else 
        return nil
    

    if let allPlayers = self.allPlayers 
        let player:EYPlayer = allPlayers[indexPath.row]
        cell.player.updatePlayerHUD(player: player)
    

    return cell

(代码未经测试)

【讨论】:

当覆盖prepareForReuse时,应该调用super。顺便说一句,我不是反对者:) @AhmadF 正确。谢谢,修复它。【参考方案4】:

制作自定义 UICollectionView 类并在需要时实现 prepareForReuse 以清除内容。

【讨论】:

以上是关于如何在重新加载时清除 UICollectionViewCell?的主要内容,如果未能解决你的问题,请参考以下文章

如何清除视图中的所有数据并重新加载?

如何使用自定义 UIViews(以及内部的转换)重新加载自定义 UICollectionViewCell

使用 Ionic 框架在登录/注销时清除历史记录并重新加载页面

如何在不清除数据库的情况下重新加载 Roo 项目?

如何重新加载圆形进度条

单击按钮时如何清除画布[重复]