如何解决在 collectionView.deleteItems 为什么我们首先需要 cell.indexPath?
我成功地从我的 collectionView 和数据源中删除了项目,但是在删除后没有调用 cellForItemAt
,所以我的索引变得一团糟。即使我在删除后立即手动调用 collectionView.reloadData()
,它也不起作用。
然而,如果我在 collectionView.reloadData()
之前的任何时间调用 collectionView.deleteItems(at: [indexPath])
,它会被调用,但显然对我没有任何好处。不知道我做错了什么,请看一看:
class ChipView: UIView {
var chips: [ChipModel]?
lazy var collectionView: UICollectionView = {
let flowLayout = LeftAlignedCollectionViewFlowLayout()
flowLayout.scrollDirection = .vertical
let result = UICollectionView(frame: frame,collectionViewLayout: flowLayout)
result.translatesAutoresizingMaskIntoConstraints = false
result.register(Chip.self,forCellWithReuseIdentifier: "Cell")
result.delegate = self
result.dataSource = self
result.backgroundColor = .clear
result.isAccessibilityElement = false
return result
}()
func deleteItem(_ sender: Chip) {
guard let chipsArray = chips,!chipsArray.isEmpty,let indexPath = sender.indexPath else { return }
// 1. remove value from source of truth
chips?.remove(at: indexPath.row)
// 2. delete item from collection view
collectionView.deleteItems(at: [indexPath])
// Todo: - figure out why cellForItemAt isn't getting called after collectionView.deleteItems... Needs to update the indexPath
collectionView.reloadData()
}
extension ChipView: UICollectionViewDataSource {
public func collectionView(_: UICollectionView,numberOfItemsInSection _: Int) -> Int {
return chips?.count ?? 0
}
public func collectionView(_ collectionView: UICollectionView,cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "Cell",for: indexPath) as! Chip
cell.indexPath = indexPath
if let chip = chips?[indexPath.row] {
cell.setupChip(title: chip.title,icon: chip.icon,chipState: chip.chipState)
}
return cell
}
}
解决方法
为什么我们首先需要 cell.indexPath?
我假设您稍后在单元格内的某个按钮点击上使用 indexPath
值以从数据源 chips?[indexPath.row]
获取模型值。
如果答案是肯定的,那么我认为避免这种情况的一种方法可能就这么简单。
public func collectionView(_ collectionView: UICollectionView,cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "Cell",for: indexPath) as! TruChip
/* Stop doing this
cell.indexPath = indexPath
*/
if let chip = chips?[indexPath.row] {
/* Stop doing this
cell.setupTruChip(title: chip.title,icon: chip.icon,chipState: chip.chipState)
*/
cell.setupTruChip(chip)
}
return cell
}
/// Inside the cell
class TruChip: UICollectionViewCell {
var currentChip: TruChipModel?
func setupTruChip(_ chip: TruChipModel) {
currentChip = chip
self.setupTruChip(title: chip.title,chipState: chip.chipState)
}
}
通过这种方法,您可以完全消除记住单元格上的 indexPath
的需要。单元格记住它在 UI 上表示的当前模型数据。
在删除之前添加批量更新为我修复它:
collectionView.performBatchUpdates {
collectionView.deleteItems(at: [indexPath])
} completion: { (finished) in
self.collectionView.reloadData()
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。