如何在重新加载时清除 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】:UICollectionViewCell
s 被重用以避免实例化,以优化性能。如果您正在滚动并且某个单元格变得不可见,则会再次使用相同的对象 (dequeueReusableCell
) 并在 cellForItemAt
...
正如前面的答案中提到的,在重用单元格之前,在单元格上调用prepareForReuse()
。所以你可以覆盖prepareForReuse()
并做任何你需要做的准备。
但是,您在每次重复使用时都会创建一个新的 EYPlayerHUDView
并将其添加到单元格中,因此您的单元格会充满堆叠的 EYPlayerHUDView
s。
为避免这种情况,将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