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

How to clear a UICollectionViewCell on reload?

我遇到一个问题,即 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 上的标签和其他信息不像上面的示例那样脏。

非常感谢

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

在您的自定义单元格 class 中使用 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 中设置您的项目 visibility/values

//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()
}

UICollectionViewCell 被重用以避免实例化,以优化性能。如果您正在滚动并且单元格变得不可见,则再次使用相同的对象 (dequeueReusableCell) 并在 cellForItemAt...[= 中设置新的 content 24=]

如前面的答案所述,在重新使用单元格之前,对单元格调用 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
}

(代码未经测试)