私は2つのCollectionViewを持っています。 1つのCollectionView(allHobbiesCV)には選択できる趣味があらかじめ設定されています。他のCollectionView(myHobbiesCV)は空ですが、allHobbiesCVの趣味をタップすると、myHobbiesCVに追加されます。これはすごく効果的です。Swift - CollectionViewセルを切り替えて配列内の項目を切り替える
タップされたallHobbiesCVセルを選択して切り替え、myHobbiesCVに趣味を追加したい場合、ユーザーがallHobbiesCVで同じ選択セルを再びタップすると、その趣味はmyHobbiesCVから削除されます。基本的にトグルの追加/削除。注意すべき
2つのこと:
- ユーザーが手動で[趣味を削除]ボタンをタップし、myHobbiesCVで趣味を選択することができます。
- 趣味は季節によってソートされるため、すべてのHobbiesArrayに4つの異なるデータセット(冬、春、夏、秋)があります。ユーザがタップする季節(ViewController)に応じて。彼らは好きなだけ多くの/いくつかの細胞を選択することができます。
問題:
私は最初のセル以外の任意のトグルにクラッシュしています。 allHobbiesCVで最初のセルを選択すると、もう一度選択してmyHobbiesCVから削除します。同じセルをもう一度選択すると(トグルするために)、私はクラッシュします。最初のセル以外のセルを選択するとクラッシュします。
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'attempt to delete item 7 from section 0 which only contains 3 items before the update'
クラスレベル
// 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]()
データソース
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
}
}
}
委任
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!
}
}
}
削除ボタン
@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.
}
}
問題は、私がdidDeselectにallHobbiesCV細胞を切り替えるしようとしています方法です。 didSelectIPArrayで選択されたセルを保存するのに正しいアプローチでしたか?
必要に応じてさらに詳しい情報をお届けします。事前に多くの友達にありがとう!
私は、インデックスを 'myHobbiesArray'に保存しません。趣味の名前を格納する。あなたが何かを削除したいときは、必要なインデックスを作るために 'myHobbiesArray.index(of:hobbyName)'を使います。 – Paulw11
@ Paulw11 - myHobbiesArrayは、私が手動で削除したい場合に備えて、選択した趣味をすべて保存しています。選択した(トグルした)セルの選択されたインデックスパスを保存しようとしている場所である "didSelectIPArray"を意味しましたか? – Joe
はい、そうする必要はありません。 – Paulw11