【问题标题】:Wrong index in button inside collectionViewCell after deletion cell删除单元格后collectionViewCell内的按钮索引错误
【发布时间】:2017-12-19 15:25:55
【问题描述】:

我有一个collectionView。每个单元格都包含按钮 actionButton 以删除它们。按钮有removeItem 方法通过附加的目标删除它们。我有一个数组 datas 包含要收集的项目。

override func collectionView(_ collectionView: UICollectionView, willDisplay cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
        super.collectionView(collectionView, willDisplay: cell, forItemAt: indexPath)
        guard let cell = cell as? ViewCell else { return }
        let index = indexPath.row % datas.count
        let item = datas[index]
        cell.item = item
        cell.actionButton.tag = indexPath.item
        cell.actionButton.addTarget(self, action: #selector(removeItem), for: .touchUpInside)
    }

我有一种方法可以从集合视图中删除项目。

@objc func removeItem(sender: UIButton) {
    let indexPath = IndexPath.init(item: sender.tag, section: 0)
    self.datas.remove(at: indexPath.item)
    collectionView?.deleteItems(at: [indexPath])
}

但在从集合单元格按钮索引中删除项目后未重新加载。例如,如果我删除索引为 [0, 0] 的第一个项目,下一个(第二个)项目变为第一个,但它的按钮索引仍然 [0, 1]。

我做错了什么以及为什么按钮索引不重新排列?

【问题讨论】:

  • 也许您也应该重新加载您的收藏视图?
  • 我尝试在collectionView?.deleteItems(at: [indexPath]) 之后添加collectionView.reloadData(),但没有帮助。
  • 无关,但为什么你的collectionView 是可选的?
  • @AlexWoe89 不,不要重新加载集合视图。仅仅删除一项就太过分了。
  • @rmaddy 不幸的是,我没有找到比self.datas.remove(at: indexPath.item) 和collectionView.reloadData() 更优雅的解决方案。目前,它是唯一有效的解决方案。我还在努力。

标签: swift uicollectionview uicollectionviewcell


【解决方案1】:

永远不要使用标签来跟踪单元格的索引路径(在集合视图或表格视图中)。如您所见,当您可以插入、删除或重新排序单元格时,它会失败。

正确的解决方案是根据按钮在集合视图中的位置来获取单元格的索引路径。

@objc func removeItem(sender: UIButton) {
    if let collectionView = collectionView {
        let point = sender.convert(.zero, to: collectionView)
        if let indexPath = collectionView.indexPathForItem(at: point) {
            self.datas.remove(at: indexPath.item)
            collectionView.deleteItems(at: [indexPath])
        }
    }
}

【讨论】:

  • 我试过你的方法,必须将let point = sender.convert(.zero, to: collectionView) 替换为let point = collectionView?.convert(CGPoint.zero, from: sender),但没有成功。我不知道为什么。
  • 定义“无效”。你得到一个合适的点吗?那你有没有合适的indexPath?无论哪种方式,您更改的行都应该给出相同的结果。
  • 你是对的,你的解决方案很好。我的问题在于按钮,它位于视图层次结构中,比我预期的要深。要抓住按钮,我看superview.superview。这是我的观点let point = collectionView.convert(sender.center, from: sender.superview?.superview)
  • 没有必要。我的答案中的代码很好。或者干脆做let point = collectionView.convert(sender.center, from: sender.superview!)。整个想法是将按钮的本地坐标转换为集合视图的坐标。
  • 您的解决方案对我来说效果很好,但您能告诉我为什么标签不适用于这种情况吗?谢谢
猜你喜欢
  • 2021-01-19
  • 2021-12-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-07-18
  • 1970-01-01
相关资源
最近更新 更多