2017-03-27 1 views
0

Ich habe zwei CollectionViews. Ein CollectionView (allHobbiesCV) ist bereits mit Hobbies gefüllt, die Sie auswählen können. Die andere CollectionView (myHobbiesCV) ist leer, aber wenn Sie in allHobbiesCV auf ein Hobby tippen, wird es zur myHobbiesCV hinzugefügt. Das funktioniert alles super.Swift - Umschalten von CollectionView-Zellen zum Umschalten von Objekten in einem Array

Ich möchte, dass die angezapften allHobbiesCV-Zellen auf selected umschalten, es fügt das Hobby zu myHobbiesCV hinzu, und wenn der Benutzer die selbe ausgewählte Zelle wieder in allHobbiesCV antippt, entfernt es dieses Hobby von myHobbiesCV. Grundsätzlich ein Toggle hinzufügen/entfernen.

Zwei Dinge zu beachten:

  1. Benutzer Hobbys in myHobbiesCV manuell auswählen und dann auf eine [entfernen Hobby] -Taste.
  2. Hobbies werden nach Jahreszeiten sortiert, so dass es für alleHobbiesArray 4 verschiedene Datensätze gibt (Winter, Frühling, Sommer, Herbst). Abhängig von welcher Jahreszeit (ViewController) tippt der Benutzer. Sie können so viele/wenige Zellen von jedem auswählen, wie sie möchten.

Problem:

ich auf jedem Umschalten neben der ersten Zelle abstürzt. Wenn ich die erste Zelle in AllHobbiesCV auswähle, kann ich sie erneut auswählen und sie aus der myHobbiesCV entfernen. Wenn ich dieselbe Zelle erneut auswähle (um sie umzuschalten), stürze ich ab. Wenn ich neben dem ersten eine andere Zelle auswähle, stürze ich ab.

*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'attempt to delete item 7 from section 0 which only contains 3 items before the update' 

Klasse 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]() 

Datenquelle

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 
    } 

} 

} 

Delegierter

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-Taste

@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. 
    } 
} 

Die Frage ist, wie ich versuche, die allHobbiesCV Zellen in didDeselect zu wechseln. War meine Vorgehensweise korrekt beim Speichern der ausgewählten Zellen in didSelectionIPArray?

Ich werde gerne weitere Einblicke geben, wenn nötig. Vielen Dank im Voraus Freunde!

+0

Ich würde den Index nicht in der 'myHobbiesArray' speichern; Speichere den Hobbynamen. Dann, wenn Sie etwas löschen möchten, verwenden Sie einfach 'myHobbiesArray.index (von: HobbyName)', um herauszufinden, welchen Index Sie brauchen – Paulw11

+0

@ Paulw11 - myHobbiesArray speichert nur alle meine ausgewählten Hobbys, falls ich manuell löschen möchte. Meinten Sie "didSelectionIPArray" - wo versuche ich den ausgewählten Indexpfad der ausgewählten (getoggten) Zellen zu speichern? – Joe

+0

Richtig ja, das ist nicht nötig. – Paulw11

Antwort

1

Es gibt keine Notwendigkeit für alle diese map und flatmap Sachen. Sie können das Objekt einfach aus dem ausgewählten Hobby-Array entfernen:

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

Wow @ Paulw11 - das ist wunderbar! Kein Absturz mehr, und das Umschalten funktioniert super !! Nur eine kurze Frage. Wie würde ich ALLEHobbiesCV-Zellen deselektieren, wenn sie unten manuell gelöscht wurden, indem Sie auswählen und dann auf Löschen tippen? Das sollte meine andere Frage beantworten, wie ich die Zellen AUSGEWÄHLT halte, sobald der Benutzer die VC ablehnt und dann zurück zu ihr geht (weil gerade jetzt alle Zellen abgewählt sind). Speichern Sie alle ausgewählten Hobbys, dann auf ViewWillAppear laden Sie die Auswahl, und deaktivieren Sie dann, wenn der gleiche Index gelöscht wurde? – Joe

+0

Ich habe meinen Code aktualisiert, um meinen Versuch hier aufzunehmen. Ich versuche, den ausgewählten Index in didSelectionIPArray zu speichern. (didSelectionIPArray.append (indexPath) in didSelectItemAt) // Dann versuche ich es in didDeselect zu entfernen (didSelectionIPArray.remove (at: indexPath.item)) // Dann, wenn ich manuell eine Zelle von myHobbies auswähle, um es zu löschen, sollte es deaktiviere die ausgewählten Zellen von allHobbies in meiner Schaltflächenaktion. Es stürzt bei allenHobbys ab, und die Löschen-Schaltfläche hebt nichts auf. Jede Hilfe wird geschätzt Paul. – Joe

+0

Ich habe dies als eine neue Frage gepostet: http://stackoverflow.com/questions/43099851/using-a-button-to-deselect-cells-in-a-collectionview - würde es lieben, wenn Sie und Ihre 35- einige Jahre Programmiererfahrung können mir helfen :) – Joe

Verwandte Themen