[英]Swift - Toggling CollectionView cells to toggle items in an Array
I have two CollectionView's. 我有两个CollectionView。 One CollectionView (allHobbiesCV) is pre-populated with Hobbies you can select. 一个CollectionView(allHobbiesCV)预先填充了您可以选择的Hobbies。 The other CollectionView (myHobbiesCV) is empty, but if you tap on a hobby in the allHobbiesCV, it gets added to the myHobbiesCV. 另一个CollectionView(myHobbiesCV)为空,但是如果在allHobbiesCV中点击一个爱好,它将被添加到myHobbiesCV中。 This is all working great. 这一切都很好。
I would like the tapped allHobbiesCV cells to switch to selected, it adds the hobby to myHobbiesCV, then if the user taps the same selected cell again in the allHobbiesCV, it removes that hobby from the myHobbiesCV. 我希望将已点击的allHobbiesCV单元格切换到选中状态,它将兴趣爱好添加到myHobbiesCV中,然后,如果用户再次在allHobbiesCV中点击相同的选定单元格,它将从myHobbiesCV中删除该兴趣爱好。 Basically a toggle add/remove. 基本上是切换添加/删除。
Two things to note: 有两件事要注意:
Problem: 问题:
I'm crashing on any toggle besides the first cell. 我在第一个单元格之外的任何切换上都崩溃了。 If I select the first cell in allHobbiesCV, I can select it again, and it will remove it from the myHobbiesCV. 如果选择allHobbiesCV中的第一个单元格,则可以再次选择它,它将从myHobbiesCV中删除它。 If I select that same cell again (to toggle it,) I crash. 如果我再次选择同一单元格(以进行切换),则会崩溃。 If I select any other cell besides the first, I crash. 如果我选择第一个单元格以外的其他任何单元格,则会崩溃。
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'attempt to delete item 7 from section 0 which only contains 3 items before the update'
Class Level 班级
// Winter Hobbies
let allHobbiesArray = ["Skiing", "Snowboarding", "Drinking Bourbon", "Snow Shoeing", "Snowmobiling", "Sledding", "Shoveling Snow", "Ice Skating"]
var myHobbiesArray = [String]()
var allSelected = [IndexPath]()
var didSelectIPArray = [IndexPath]()
Data Source 数据源
extension ViewController: UICollectionViewDataSource {
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.item]
if cell.isSelected {
cell.backgroundColor = UIColor.green
}
else {
cell.backgroundColor = UIColor.yellow
}
return cell
}
else {
let cell = myHobbiesCV.dequeueReusableCell(withReuseIdentifier: "MY", for: indexPath) as! MyHobbiesCell
cell.myHobbiesLabel.text = myHobbiesArray[indexPath.item]
if cell.isSelected {
cell.backgroundColor = UIColor.red
}
else {
cell.backgroundColor = UIColor.yellow
}
return cell
}
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
if collectionView == allHobbiesCV {
return allHobbiesArray.count
}
else {
return myHobbiesArray.count
}
}
}
Delegate 代表
extension ViewController: UICollectionViewDelegate {
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
if collectionView == allHobbiesCV {
if myHobbiesArray.count <= 6
self.allSelected = []
didSelectIPArray.append(indexPath) // Store the selected indexPath in didSelectIPArray
myHobbiesArray.insert(allHobbiesArray[indexPath.item], at: 0)
let allHobbiesCell = allHobbiesCV.cellForItem(at: indexPath) as! AllHobbiesCell
allHobbiesCell.backgroundColor = UIColor.green
// Store all of the selected cells in an array
didSelectIPArray.append(indexPath)
myHobbiesCV.reloadData()
}
}
else {
let cell = myHobbiesCV.cellForItem(at: indexPath) as! MyHobbiesCell
cell.backgroundColor = UIColor.red
allSelected = self.myHobbiesCV.indexPathsForSelectedItems!
}
}
// Deselecting selected cells
func collectionView(_ collectionView: UICollectionView, didDeselectItemAt indexPath: IndexPath) {
if collectionView == allHobbiesCV {
// Yellow is the unselected cell color. So let's change it back to yellow.
let allHobbiesCell = allHobbiesCV.cellForItem(at: indexPath) as! AllHobbiesCell
allHobbiesCell.backgroundColor = UIColor.yellow
// Remove (toggle) the cells. This is where I am stuck/crashing.
let indices = didSelectIPArray.map{ $0.item }
myHobbiesArray = myHobbiesArray.enumerated().flatMap { indices.contains($0.0) ? nil : $0.1 }
self.myHobbiesCV.deleteItems(at: didSelectIPArray)
myHobbiesCV.reloadData()
didSelectIPArray.remove(at: indexPath.item) // Remove the deselected indexPath from didSelectIPArray
}
else { // MyHobbies CV
let cell = myHobbiesCV.cellForItem(at: indexPath) as! MyHobbiesCell
cell.backgroundColor = UIColor.yellow
// Store the selected cells to be manually deleted.
allSelected = self.myHobbiesCV.indexPathsForSelectedItems!
}
}
}
Delete Button 删除按钮
@IBAction func deleteButtonPressed(_ sender: UIButton) {
for item in didSelectIPArray {
self.allHobbiesCV.deselectItem(at: item, animated: false) // Try deselecting the deleted items in allHobbiesCV... This is crashing.
}
}
The issue is how I am trying to toggle the allHobbiesCV cells in didDeselect. 问题是我如何尝试切换didDeselect中的allHobbiesCV单元。 Was my approach correct in saving the selected cells in didSelectIPArray? 我的方法在将所选单元格保存在didSelectIPArray中是否正确?
I'll be happy to provide further insight if needed. 如果需要,我很乐意提供进一步的见解。 Thank you much in advance friends! 预先感谢您的朋友!
There is no need for all of that map
and flatmap
stuff. 不需要所有这些map
和flatmap
东西。 You can simply remove the object from the selected hobbies array: 您可以简单地从选定的兴趣爱好数组中删除对象:
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
if collectionView == allHobbiesCV {
if myHobbiesArray.count <= 6
self.allSelected = []
myHobbiesArray.insert(allHobbiesArray[indexPath.item], at: 0)
let allHobbiesCell = allHobbiesCV.cellForItem(at: indexPath) as! AllHobbiesCell
allHobbiesCell.backgroundColor = UIColor.green
myHobbiesCV.insertItems(at: [IndexPath(item: 0, section: 0)])
}
} else {
let cell = myHobbiesCV.cellForItem(at: indexPath) as! MyHobbiesCell
cell.backgroundColor = UIColor.red
allSelected = self.myHobbiesCV.indexPathsForSelectedItems!
}
}
func collectionView(_ collectionView: UICollectionView, didDeselectItemAt indexPath: IndexPath) {
if collectionView == allHobbiesCV {
// Yellow is the unselected cell color. So let's change it back to yellow.
let allHobbiesCell = allHobbiesCV.cellForItem(at: indexPath) as! AllHobbiesCell
allHobbiesCell.backgroundColor = UIColor.yellow
let hobby = allHobbiesArray[indexPath.item]
if let index = myHobbiesArray.index(of:hobby) {
myHobbiesArray.remove(at: index)
myHobbiesCV.deleteItems(at: [IndexPath(item: index, section:0)])
}
} else { // MyHobbies CV
let cell = myHobbiesCV.cellForItem(at: indexPath) as! MyHobbiesCell
cell.backgroundColor = UIColor.yellow
// Store the selected cells to be manually deleted.
allSelected = self.myHobbiesCV.indexPathsForSelectedItems!
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.