2017-03-27 25 views
0

私は2つのCollectionViewを持っています。 1つのCollectionView(allHobbiesCV)には選択できる趣味があらかじめ設定されています。他のCollectionView(myHobbiesCV)は空ですが、allHobbiesCVの趣味をタップすると、myHobbiesCVに追加されます。これはすごく効果的です。Swift - CollectionViewセルを切り替えて配列内の項目を切り替える

タップされたallHobbiesCVセルを選択して切り替え、myHobbiesCVに趣味を追加したい場合、ユーザーがallHobbiesCVで同じ選択セルを再びタップすると、その趣味はmyHobbiesCVから削除されます。基本的にトグルの追加/削除。注意すべき

2つのこと:

  1. ユーザーが手動で[趣味を削除]ボタンをタップし、myHobbiesCVで趣味を選択することができます。
  2. 趣味は季節によってソートされるため、すべての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で選択されたセルを保存するのに正しいアプローチでしたか?

必要に応じてさらに詳しい情報をお届けします。事前に多くの友達にありがとう!

+0

私は、インデックスを 'myHobbiesArray'に保存しません。趣味の名前を格納する。あなたが何かを削除したいときは、必要なインデックスを作るために 'myHobbiesArray.index(of:hobbyName)'を使います。 – Paulw11

+0

@ Paulw11 - myHobbiesArrayは、私が手動で削除したい場合に備えて、選択した趣味をすべて保存しています。選択した(トグルした)セルの選択されたインデックスパスを保存しようとしている場所である "didSelectIPArray"を意味しましたか? – Joe

+0

はい、そうする必要はありません。 – Paulw11

答えて

1

そのすべての必要はありませんmapflatmapものです。

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! 

    } 
} 
+0

うわー@ Paulw11 - これは素晴らしいです!もはやクラッシュすることはなく、トグル動作は素晴らしい!ただの簡単な質問です。手動で以下で削除を選択してから削除すると、どのようにallHobbiesCVセルをDESELECTするのですか?それは、ユーザーがVCを却下した後、それをセグに戻す(今はすべてのセルが選択解除されているため)、セルを選択したままにしておきたいという私の他の質問に答えるべきです。選択したすべての趣味を保存し、次にviewWillAppearに選択をロードして、同じインデックスが削除されている場合は選択解除しますか? – Joe

+0

ここに私の試行を含めて私のコードを更新しました。選択したインデックスをdidSelectIPArrayに保存しようとしています。 (didSelectIPArray.append(indexPath)in didSelectItemAt)//次にdidDelectlect(didSelectIPArray.remove(at:indexPath.item))で削除してみます//最後に、myHobbiesからセルを手動で選択して削除すると、ボタン操作でallHobbiesから選択したセルの選択を解除します。すべての趣味がクラッシュしています。趣味は選択を解除し、削除ボタンは何も選択解除しません。どんな助けもポールに感謝します。 – Joe

+0

私はこれを新しい質問として投稿しました:http://stackoverflow.com/questions/43099851/using-a-button-to-deselect-cells-in-a-collectionview - プログラミングの経験の何年かは私を助けることができます:) – Joe

関連する問題