我有一个String
数组,填充了我的UICollectionView
单元格,并有一个标签标题。
在我的情况下,我希望用户从此Collection中选择多个行/项目,然后点击一个按钮,删除所有未选择的项目,只保留选定的项目。
为此,我有一个具有数据源indexPath项的辅助数组,以及一个跟踪所选行的第三个数组。
执行此操作后,我会更新DataSource
,然后更新performBatchUpdates(:_)
因为我喜欢调用collectionView.delete(:_)
时提供的动画。
此处的问题出现在我的DataSource
删除中,因为它会自行迭代,删除项目,这样做会缩短自身,有时会得到Index out of range
。
假设我要移除项12
和13
删除12
,自行更新,当它尝试删除项13
时,DataSource
没有13项,只有12项。
这是我正在使用的代码:
private var dataSource: [String] = [
"ARTS",
"BUSINESS",
"COMEDY",
"CULTURE",
"GAMES",
"HEALTH",
"MUSIC",
"NEWS",
"POLITICS",
"RELIGION",
"SCIENCE",
"SPORTS",
"TECH",
"TV & FILM"
]
private var selectedIndexes = [IndexPath]()
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
let cell = collectionView.cellForItem(at: indexPath) as! InterestsCollectionViewCell
selectedIndexes.append(indexPath)
}
@objc func didTapNextButton() {
var dataSourceIndexes = [IndexPath]()
dataSourceIndexes.removeAll()
for (i, _) in dataSource.enumerated() {
let ip = IndexPath(item: i, section: 0)
dataSourceIndexes.append(ip)
}
selectedIndexes.forEach { (indexPath) in
dataSourceIndexes.remove(at: indexPath.item)
}
var indexSet: Set = [0]
indexSet.removeAll()
dataSourceIndexes.forEach { (ip) in
let i = ip.item
indexSet.insert(i)
}
dataSource = dataSource.enumerated().filter { !indexSet.contains($0.offset) }.map {$0.element }
// updates the UI
collectionView.performBatchUpdates({
collectionView.deleteItems(at: dataSourceIndexes)
}, completion: nil)
}
你能注意到我做错了什么吗?为了避免这种情况,还有什么要改进的吗?
谢谢
修改
所以为了解决这个问题,我不得不打电话:
selectedIndexes = selectedIndexes.sorted()
通过这个我避免了用户选择项目的顺序,然后我不得不以反向模式调用forEach
,如下所示:
selectedIndexes.reversed().forEach { (indexPath) in
dataSourceIndexes.remove(at: indexPath.item)
}
感谢@LeoDabus提示以相反的顺序调用selectedIndex
。