我有一个带有非常简单数据源的UICollectionView。它只是一个以编程方式更新的字符串数组。使用此UICollectionView,我可以点击选择多个单元格 - 然后可以使用“删除”按钮删除所有选定的单元格。很简单,除了我有时会出现致命错误:索引超出范围。
通过在另一个名为" All Hobbies" - 无论是哪种细胞都可以使用在"所有爱好"中选择简历被添加到"我的爱好。"我这样做是通过将tapped cell的值附加到控制My Hobbies CV的数组。
问题
似乎我的数据在删除后没有更新,当我再次尝试删除时,索引超出范围。但是,我无法在我的代码中找到导致这种情况发生的问题(如果这确实是问题......)
班级
let allHobbiesArray = ["Skiing", "Jogging", "Bicycling", "Basketball", "Cricket", "Being a Couch Potato", "Skiing", "Jogging", "Bicycling", "Basketball", "Cricket", "Being a Couch Potato", "Skiing", "Jogging", "Bicycling", "Basketball", "Cricket", "Being a Couch Potato", "Skiing", "Jogging", "Bicycling", "Basketball", "Cricket", "Being a Couch Potato"]
var myHobbiesArray = [String]()
var allSelected = [IndexPath]()
数据来源
func numberOfSections(in collectionView: UICollectionView) -> Int {
return 1
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
if collectionView == allHobbiesCV {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "ALL", for: indexPath) as! AllHobbiesCell
cell.allHobbiesLabel.text = allHobbiesArray[indexPath.row]
return cell
}
else {
let cell = myHobbiesCV.dequeueReusableCell(withReuseIdentifier: "MY", for: indexPath) as! MyHobbiesCell
cell.myHobbiesLabel.text = myHobbiesArray[indexPath.row]
return cell
}
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
if collectionView == allHobbiesCV {
return allHobbiesArray.count
}
else {
return myHobbiesArray.count
}
}
代表
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
if collectionView == allHobbiesCV {
let cell = allHobbiesCV.cellForItem(at: indexPath) as! AllHobbiesCell
myHobbiesArray.append(allHobbiesArray[indexPath.row])
myHobbiesCV.reloadData()
for i in 0..<allSelected.count {
self.myHobbiesCV.selectItem(at: allSelected[i], animated: false, scrollPosition: [])
}
}
else {
let cell = myHobbiesCV.cellForItem(at: indexPath) as! MyHobbiesCell
cell.backgroundColor = UIColor.red // Red background to show that it's selected
// Store all of the selected cells in allSelected
allSelected = self.myHobbiesCV.indexPathsForSelectedItems!
}
}
func collectionView(_ collectionView: UICollectionView, didDeselectItemAt indexPath: IndexPath) {
if collectionView == allHobbiesCV {
let cell = allHobbiesCV.cellForItem(at: indexPath) as! AllHobbiesCell
cell.backgroundColor = UIColor.yellow
}
else {
let cell = myHobbiesCV.cellForItem(at: indexPath) as! MyHobbiesCell
cell.backgroundColor = UIColor.yellow
// update allSelected after deselect
allSelected = self.myHobbiesCV.indexPathsForSelectedItems!
}
}
删除单元格
@IBAction func deleteButtonPressed(_ sender: UIButton) {
if allSelected.count > 0 {
for element in allSelected {
removeSelectedCells(i: element.item)
}
}
}
func removeSelectedCells(i: Int) {
self.myHobbiesArray.remove(at: i) // This is what Xcode shows as the crash on the fatal error.
let indexPath = NSIndexPath(row: i, section: 0)
self.myHobbiesCV.deleteItems(at: NSArray(object: indexPath) as! [IndexPath])
//self.myHobbiesCV.performBatchUpdates({
// self.myHobbiesCV.deleteItems(at: NSArray(object: indexPath) as! [IndexPath])
//}) { (true) in
// self.myHobbiesCV.reloadData()
//}
}
非常感谢任何帮助处理从集合视图中删除多个单元格。如果您需要更多信息,我将很乐意澄清。
答案 0 :(得分:1)
使用SO回答here,您应该能够从allSelected
indexPaths数组中获取索引,然后立即从myHobbiesArray
中删除所有索引。
@IBAction func deleteButtonPressed(_ sender: UIButton) {
let indices = allSelected.map{ $0.item }
myHobbiesArray = myHobbiesArray.enumerated().flatMap { indices.contains($0.0) ? nil : $0.1 }
self.myHobbiesCV.deleteItems(at: allSelected)
}