addSubview über didSelectItemAt ?

Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

  • addSubview über didSelectItemAt ?

    Hallo,

    weiß einer von euch ob es möglich ist üb die Funktion collectionView didSelectItemAt einer bereits vorhandenen View eine Subview anzuhängen ? Ich probiere das jetzt schon ne ganze weile und frage mich warum das nicht so recht funktionieren will.

    Also ich würde gerne die Subview sehen wenn ich auf eine Zelle klicke. Mache ich irgendwas falsch oder gibt es eine andere Lösung für das Problem

    Quellcode

    1. override func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
    2. let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "Cell", for: indexPath)
    3. let picture = imageArray[indexPath.row]
    4. let testView = UIView(frame: CGRect(x: 0, y: 0, width: cell.frame.size.width, height: cell.frame.size.height))
    5. testView.backgroundColor = .red
    6. if pickedImages.count == 5 {
    7. print("maximale Anzahl erreicht")
    8. } else {
    9. cell.addSubview(testView)
    10. pickedImages.append(picture)
    11. }
    12. }
    Alles anzeigen
  • dequeueReusableCell(withReuseIdentifier:for:) solltest Du nur in der Methode collectionView(_:cellForItemAt:) verwenden.

    Um eine angezeigte Zelle aus einem Collection View zu erhalten gibt es die Methode cellForItem(at:).

    Anstatt die Zelle direkt in collectionView(_:didSelectItemAt:) zu verändern, solltest Du lieber ein Flag/Status oder dergleichen in Deinem Datenmodel setzen und dann ein reloadItems(at:) für die Zelle ausführen, um diese Änderung in collectionView(_:cellForItemAt:), je nach Flag/Status im Datenmodell, durchzuführen.

    Deine aktuelle Lösung funktioniert nicht mehr, wenn Du die Zelle aus dem sichtbaren Bereich heraus und dann wieder herein scrollst, da dann durch collectionView(_:cellForItemAt:) evtl. eine neue oder andere Zelle verwendet wird.
  • Okay also ich habe versucht das jetzt mal so in etwa umzusetzen. Wusste nicht ganz wie ich deine Idee mit dem Status umsetzen sollte also hab ich das wie folgt gemacht.
    An sich funktioniert das ganze schon fast komplett. Ein Problem habe ich aber noch und zwar möchte ich das die Subview wieder verschwindet wenn ein zweites mal auf die Zelle geklickt wurde. Zwar leert sich das Array pickedImages wenn eine Zelle zwei mal angeklickt wurde jedoch verschwindet die subView nur bei der ersten Zelle die ich wiederholt angeklickt habe.
    Alle anderen Zellen verschwinden zwar aus dem Array, behalten jedoch ihre subView....Warum ?

    Quellcode

    1. override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    2. let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "Cell", for: indexPath)
    3. let imageView = cell.viewWithTag(1) as! UIImageView
    4. imageView.image = imageArray[indexPath.row]
    5. for value in pickedImages {
    6. if value == imageView.image {
    7. let testView = UIView(frame: CGRect(x: 0, y: 0, width: 25, height: 25))
    8. testView.backgroundColor = .red
    9. cell.addSubview(testView)
    10. }
    11. }
    12. return cell
    13. }
    Alles anzeigen

    Quellcode

    1. override func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
    2. let picture = imageArray[indexPath.row]
    3. if pickedImages.count == 5 {
    4. print("maximale Anzahl erreicht")
    5. } else if pickedImages.contains(picture) {
    6. print("Bereits vorhanden")
    7. for (index, value) in pickedImages.enumerated() where value == picture {
    8. pickedImages.remove(at: index)
    9. collectionView.reloadItems(at: [indexPath])
    10. }
    11. } else {
    12. pickedImages.append(picture)
    13. collectionView.reloadItems(at: [indexPath])
    14. }
    15. print(pickedImages)
    16. }
    Alles anzeigen
  • hab ich schon ausprobiert jedoch hat das nicht geholfen.

    Meinst sicherlich so oder ?

    Quellcode

    1. override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    2. let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "Cell", for: indexPath)
    3. let imageView = cell.viewWithTag(1) as! UIImageView
    4. imageView.image = imageArray[indexPath.row]
    5. let testView = UIView(frame: CGRect(x: 0, y: 0, width: 25, height: 25))
    6. testView.backgroundColor = .red
    7. for value in pickedImages {
    8. if value == imageView.image {
    9. cell.addSubview(testView)
    10. } else {
    11. testView.removeFromSuperview()
    12. }
    13. }
    14. return cell
    15. }
    Alles anzeigen


    EDIT:

    Hab jetzt nochmal weiter rum probiert und alles mögliche ausprobiert aber irgendwas scheint da nicht zu klappen und ich weiß absolut nicht woran das liegt. Hier nochmal ein anderer Versuch:

    Quellcode

    1. override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    2. let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "Cell", for: indexPath)
    3. let imageView = cell.viewWithTag(1) as! UIImageView
    4. imageView.image = imageArray[indexPath.row]
    5. let picture = imageArray[indexPath.row]
    6. let testView = UIView(frame: CGRect(x: 0, y: 0, width: 25, height: 25))
    7. testView.backgroundColor = .red
    8. for value in pickedImages {
    9. if value == imageView.image {
    10. cell.addSubview(testView)
    11. }
    12. }
    13. if pickedImages.contains(picture) == false {
    14. testView.removeFromSuperview()
    15. }
    16. return cell
    17. }
    Alles anzeigen

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von ThisIsBeat ()

  • So wird es auch nicht funktionieren. In der letzten Version erzeugst Du immer einen neuen testView und fügst diesen dann zur CollectionViewCell hinzu oder Du versuchst diesen neuen testView zu entfernen, obwohl er sich ja noch gar nicht in der CollectionViewCell befinden kann.

    Das Thema hatten wir schon mehrfach und die Lösungen dazu gab es auch schon mehrfach. Du kannst den testView direkt im Storyboard für die CollectionViewCell anlegen und dann z.B. bei Bedarf anzeigen oder nicht (Stichwort isHidden).

    Wenn Du den testView unbedingt per Source Code erzeugen und hinzufügen möchtest, dann musst Du natürlich vorab prüfen ob sich der testView evtl. schon in der CollectionViewCell befindet (Stichwort Reused Cells), wenn es sich um eine Zelle handelt, die bereits verwendet wurde. Da gibt es dann mehrere Möglichkeiten z.B. per viewWithTag(_:), was auch schon angesprochen wurde. ;)
  • Nun gut habe es dann jetzt mal so gemacht wie du meintest und siehe da es klappt aber eine Sache gibt es da die trotzdem komisch ist. Das ganze funktioniert nur wenn ich folgende Zeile nicht benutze:
    testView = UIView(frame: CGRect(x: 0, y: 0, width: 25, height: 25))

    Warum ? Dann hätte es vielleicht auch bei einem meiner anderer Versuche geklappt...

    hier der gesamte Code:

    Quellcode

    1. override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    2. let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "Cell", for: indexPath)
    3. let imageView = cell.viewWithTag(1) as! UIImageView
    4. imageView.image = imageArray[indexPath.row]
    5. var testView = cell.viewWithTag(2) as! UIView
    6. //testView = UIView(frame: CGRect(x: 0, y: 0, width: 25, height: 25)) funktioniert nicht mit dieser Zeile
    7. testView.backgroundColor = .red
    8. testView.isHidden = true
    9. for value in pickedImages {
    10. if value == imageView.image {
    11. testView.isHidden = false
    12. cell.addSubview(testView)
    13. } else {
    14. testView.isHidden = true
    15. }
    16. }
    17. return cell
    18. }
    Alles anzeigen
  • Interessant, dass es so funktioniert. Dies würde ich anhand des Source Codes nicht vermuten.

    Meine Lösung würde etwa so aussehen:

    C-Quellcode

    1. override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    2. let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "Cell", for: indexPath)
    3. let imageView = cell.viewWithTag(1) as! UIImageView
    4. imageView.image = imageArray[indexPath.row]
    5. var testView = cell.viewWithTag(2) as! UIView
    6. if pickedImages.contains(imageView.image) {
    7. if testView == nil {
    8. testView = UIView(frame: CGRect(x: 0, y: 0, width: 25, height: 25))
    9. testView.tag = 2
    10. testView.backgroundColor = .red
    11. testView.isHidden = true
    12. cell.addSubview(testView)
    13. }
    14. testView.isHidden = false
    15. } else if testView {
    16. testView.isHidden = true
    17. }
    18. return cell
    19. }
    Alles anzeigen
  • Das funktioniert so nicht da testView zum einen ja kein Bool ist somit wird für deine else if schleife ein Fehler geworfen und zum anderen da testView ja ein non- optional value ist.

    Also ich hab jetzt das Problem mit dem Frame einfach im Storyboard gelöst. Weiß jetzt auch nicht warum das nicht im Code funktionieren möchte. Aber so passt jetzt alles.

    Trotzdem vielen vielen Dank für die Hilfe, hilft mir immer weiter ! :)