如何从 UICollectionView 中正确删除单元格?
Posted
技术标签:
【中文标题】如何从 UICollectionView 中正确删除单元格?【英文标题】:How to correctly delete a cell from UICollectionView? 【发布时间】:2019-04-15 13:51:22 【问题描述】:我正在尝试从 UICollectionView 中删除单元格,但出现“无效更新”错误
'无效更新:第0节中的项目数无效。更新后现有节中包含的项目数(9)必须等于更新前该节中包含的项目数(9),加上或减去从该部分插入或删除的项目数(0 插入,1 个删除),加上或减去移入或移出该部分的项目数(0 移入,0 移出)。'
我尝试在从 CollectionView 中删除项目之前更新我的 DataModel,但没有成功。
这是我的代码:
func didChangeQunatityOfCartProductAt(index: IndexPath?, product: ItemsModel?)
if let quantity = product?.quantity
if let indexPath = index
if quantity == 0
self.products.remove(at: indexPath.row)
self.collectionView.deleteItems(at: [indexPath])
这是我的 numberOfItemsInSection 函数:
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int
return products.count
即使我在网上找到的所有解决方案都是相同的,但我仍然得到相同的结果。
【问题讨论】:
在主线程上做所有事情,也许......? 你能分享你在 collectionView:numberOfItemsInSection 中的代码吗? @JonRose 请查看更新后的问题 在 self.products.remove(at: indexPath.row) 行之后检查产品数组。数据是否已成功从产品中移除? 看看 WWDC 会议A Tour of UICollectionView。他们描述了如何正确更新模型和集合视图。幻灯片 50 - 62。 【参考方案1】:你应该试试collectionview的performBatchUpdates(_:completion:)
func didChangeQunatityOfCartProductAt(index: IndexPath?, product: ItemsModel?)
if let quantity = product?.quantity
if let indexPath = index
if quantity == 0
self.products.remove(at: indexPath.row)
self.collectionView.performBatchUpdates(
self.collectionView.deleteItems(at: [indexPath])
)
// optional closure
【讨论】:
【参考方案2】:我发现了问题,我在删除索引处的项目后自动重新加载集合视图,其中 products 数组在类的顶部有一个属性观察器,它重新加载集合视图,并且在删除它之后修复了问题
【讨论】:
【参考方案3】:您可以尝试从 dataSource 数组中删除数据并调用 reloadData 方法来“刷新”您的 collectionViewDatasource
func didChangeQunatityOfCartProductAt(index: IndexPath?, product: ItemsModel?)
if let quantity = product?.quantity
if let indexPath = index
if quantity == 0
self.products.remove(at: indexPath.row)
self.collectionView.reloadData()
这里唯一的区别是将单元格删除替换为:
self.collectionView.reloadData()
【讨论】:
reloadData() 导致 collectionView 一直滚动到屏幕顶部,这不好【参考方案4】:您应该从 array(Products) 中删除 indexPath.item,因为它是 indexPath.row 的集合视图。
func didChangeQunatityOfCartProductAt(index: IndexPath?, product: ItemsModel?)
if let quantity = product?.quantity
if let indexPath = index
if quantity == 0
DispatchQueue.global(qos: .userInteractive).async [weak self] in
self.products.remove(at: indexPath.item)
DispatchQueue.main.async [weak self] in
self?.collectionView.deleteItems(at: [indexPath])
self?.collectionView.reloadData() // or you can reload the specific indexPath
【讨论】:
我试过之后还是有同样的问题【参考方案5】:如果您的产品数量为 0,您如何删除产品? 您应该从该代码中删除 self.products.remove,因为该产品不再存在。
func didChangeQunatityOfCartProductAt(index: IndexPath?, product: ItemsModel?)
if let quantity = product?.quantity
if let indexPath = index
if quantity == 0
self.collectionView.deleteItems(at: [indexPath])
【讨论】:
以上是关于如何从 UICollectionView 中正确删除单元格?的主要内容,如果未能解决你的问题,请参考以下文章
从 Storyboard 加载的 UICollectionView 未正确调整大小
UITableViewCell 中的 UICollectionView 如何设置选择以将数据从当前视图传递到另一个视图
如何在使用自定义单元格的 UICollectionView 中正确设置异步图像下载?