【问题标题】:How to clear a UICollectionViewCell on reload?如何在重新加载时清除 UICollectionViewCell?
【发布时间】: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 上的标签和其他信息不会像上面的示例那样脏。

非常感谢

【问题讨论】:

  • 您的回答有帮助。虽然代码在 Objective C 中;我能够根据我的要求修改和更新它!
  • 在您的自定义单元格类中覆盖 prepareForResure 方法并添加所需的清理。
  • 但是没有自定义单元格类。考虑;集合视图单元格是空的,除了添加子视图之外什么都不做。

标签: ios swift uicollectionviewcell reload


【解决方案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 以清除内容。

    【讨论】:

      猜你喜欢
      • 2016-01-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-02-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多