9

Ich versuche, eine Collection View tun, wobei jemand eine cell wählt und für jede Auswahl nimmt sie eine andere View Controller, die Inhalt der Auswahl enthält. Allerdings stoße ich in Schwierigkeiten, sobald ich diese Codezeile auf didSelectItemAtIndexPath anwenden;Swift: UICollectionView Auswahl Zelle indexPath Probleme

self.performSegueWithIdentifer("showDetail", sender: self) 

und dann die cell Auswahl im Simulator laufen arbeiten daran, die indexPath nach aber seine der Auswahl jedes Mal, wenn ich neue cell wählen zu erinnern. Also zum Beispiel jede cell hat ein Foto und ein Etikett und wenn ich die erste cell in der indexPath die segue die mich zuerst auf leere Sicht und dann auf meine ausgewählten cell. Wenn ich eine andere cell, Nummer 3 auf indexPath wähle, ist die leere Ansicht jetzt die erste cell von meiner vorherigen Wahl, nach der es zu meiner ausgewählten dritten cell dauert. Es macht das jedes Mal. Wenn ich den performSegueWithIdentifer Code entferne (von Xcode 6.2 (in 6.1.1 war es zufällig)) ist die Auswahl meine vorherige Wahl und nie meine 'selectedCell', aber dann ist es zumindest einmal Auswahl statt zweimal, um zu view zu gelangen. Auf dem indexPath läuft etwas schief. Dies ist der Code für meine prepareForSegue

override func prepareForSegue(segue: UIStoryBoardSegue, sender: AnyObject?) { 
     if segue.identifer == "showDetail" { 
      let detailVC:DetailViewController = segue.destinationViewController as DetailViewController 
      detailVC.selectedImageName = selectedImage 
      detailVC.selectedLabel = selectedLabels 
      } 
     } 

Ich bin fest auf das, was & zu tun, was Lösung anzuwenden. Halte ich performSegueWithIdentifer Code & ein Equatable erstellen, um find(array, selection) auf dem indexPath zu implementieren? Oder könnte ich eine Schleife schreiben, (die viel einfacher scheint), die durch die indexPath basierend auf den Auswahlen laufen würde und die die Zelle entfernen würde, die nicht mehr ausgewählt ist. Ich bin mir jedoch nicht sicher, welche Bedingung ich in die Schleife schreiben soll, weil ich den Wert der Eigenschaft 'selectedCell' nicht kenne, weil es optional ist.

for (index, value) in enumerate(cellItems) { 
//something here to remove 'selectedItem' in the indexPath 
} 

Wenn ich entfernen performSegueWithIdentifer Code aus didSelectItemAtIndexPath was kann ich in meiner prepareForSegue tun, um die Auswahl auf den richtigen indexPath zu bekommen?

EDIT der vollständige Code auf didSelectItemAtIndexPath

override func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) { 
    selectedImage = cellImages[indexPath.row] as String 
    selectedLabels = cellLabels[indexPath.row] as String 
    self.performSegueWithIdentifer("showDetail", sender: self) 
    } 

Ich habe versucht, Absender indexPath im performSegueWithIdentifer ändern, aber das Problem bleibt.

EDIT 2 komplette Code meiner CollectionViewController

class CollectionViewController: UIViewController, UICollectionViewDataSource, UICollectionViewDelegate { 

@IBOutlet weak var collectionView: UICollectionView! 

var selectedImage = String() 
var selectedLabels = String() 

var cellImages:[String] = ["1.jpg", "2.jpg", "3.jpg", "4.jpg", "5.jpg", "6.jpg", "7.jpg", "8.jpg", "9.jpg", "10.jpg", "11.jpg", "13.jpg", "14jpg"] 

var cellLabels:[String] = ["Photo 1", "Photo 2", "Photo 3", "Photo 4", "Photo 5", "Photo 6", "Photo 7", "Photo 8", "Photo 9", "Photo 10", "Photo 11", "Photo 12", "Photo 13", "Photo 14"] 

func collectionView(collectionView: UICollectionView, numberOfNumberItemsInSection: Int) -> Int { 
    return cellImages.count 
} 

func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell { 
    let cell: PhotoViewCell = collectionView.dequeueReuseableCellWithReuseIdentifier("Cell", forIndexPath: indexPath) as PhotoViewCell 
    cell.labelCell.text = cellLabels[indexPath.row] 
    cell.ImageCell.image = UIImage(named: cellImages[indexPath.row]) 
    return cell 
} 

override func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) { 
    selectedImage = cellImages[indexPath.row] as String 
    selectedLabels = cellLabels[indexPath.row] as String 
    self.performSegueWithIdentifer("showDetail", sender: self) 
    } 

override func prepareForSegue(segue: UIStoryBoardSegue, sender: AnyObject?) { 
     if segue.identifer == "showDetail" { 
      let detailVC:DetailViewController = segue.destinationViewController as DetailViewController 
      detailVC.selectedImageName = selectedImage 
      detailVC.selectedLabel = selectedLabels 
      } 
     } 
} 

PhotoViewCell

class PhotoViewCell: UICollectionViewCell { 

@IBOutlet var labelCell: UILabel! 
@IBOutlet var ImageCell: UIImage! 

} 

EDIT 3 - Geänderte

ich Ihren Vorschlag versucht und leider ist das Problem auf doppelte Ansichten persistierenden noch - es ist immer noch zwei Ansichten, bevor es mich zu dem tatsächlich ausgewählten cell führt. Ich habe den Code auch leicht in der didSelectItemAtIndexPath geändert, aber es hat das Problem immer noch nicht behoben.

if let cell = collectionView.cellForItemAtIndexPath(indexPath) as? PhotoViewCell { 

performSegueWithIdentifier("showDetail", sender: cell) 
} 

jedoch Vorschlag nach Ihrem anderen, in meinem StoryBoard ich segue von meinem Collection Viewcell meinen DetailViewController hinzugefügt, die die Kennung „showdetail“ hat. Wenn ich segue entferne, kann nichts aus meiner cells ausgewählt werden.

Obwohl es das scheint performSegueWithIdentifer Code der Auslöser für die Doppel Ansichten ist, denn wenn ich es entfernen, wird die cell nur einmal gewählt ist, war das Problem, dass die indexPath der cell Auswahl nicht korrekt war, weil es zuerst ist die Auswahl auf eine leere Ansicht (ist das mit der ShowDetail segue zu tun?), die dann meine indexPath aus der Synchronisation bringt.

EDIT - Gelöst

Dies stoppte die Doppel Auswahlen (die performSegueWithIdentifier Linie wurde entfernt): -

override func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) { 
if let cell = collectionView.cellForItemAtIndexPath(indexPath) { 
cellLabels[indexPath.row] as String 
cellImages[indexPath.row] as String 
    } 
} 

Vielen Dank für Ihre Hilfe !!!!

+0

wo Sie SelectedImage und selectedLabel eingestellt? Sie können den IndexPath an den Absender self.performSegueWithIdentifer ("showDetail", sender: indexPath) senden und dann in preparedforsegue das Element des Arrays mit diesem indexpath aufnehmen. – Godfather

+0

@ user588125 Das ausgewählte Image und das ausgewählte Label werden im didSelectItemAtIndexPath festgelegt. Ich habe dieses self.performSegueWithIdentifer ("showDetail", sender: indexPath) versucht, aber es hat nicht funktioniert. Wie schreibe ich das in eine Bedingung in prepareForSegue? – j03T

+0

Lassen Sie Element = yourArray [indexPath.row]; detailVC.selectedImage = element.selectedImage ... kann ohne den eigentlichen Code nicht mehr tun. – Godfather

Antwort

9

Ich bleibe bei UIView Objekte so viel wie möglich.

override func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) { 
    if let cell = collectionView.cellForItemAtIndexPath(indexPath) { 
     performSegueWithIdentifier("showDetail", sender: cell) 
    } else { 
     // Error indexPath is not on screen: this should never happen. 
    } 
} 

Dann in func prepareForSegue(,sender:)

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) { 
    assert(sender as? UICollectionViewCell != nil, "sender is not a collection view") 

    if let indexPath = self.collectionView?.indexPathForCell(sender as UICollectionViewCell) { 
     if segue.identifier == "showDetail" { 
      let detailVC: DetailViewController = segue.destinationViewController as DetailViewController 
      detailVC.selectedImageName = cellImages[indexPath.row] 
      detailVC.selectedLabel = cellLabels[indexPath.row] 
     } 
    } else { 
     // Error sender is not a cell or cell is not in collectionView. 
    } 
} 

Ich habe den Verdacht, dass Sie eine segue im Storyboard haben bereits und müssen nicht func collectionView(, didSelectItemAtIndexPath:), aber so oder so, sollte die Vorbereitung segue arbeiten.

1

Swift 3,0

override func prepare(for segue: UIStoryboardSegue, sender: Any?) { 

    let iPath = self.collectionView.indexPathsForSelectedItems 
    let indexPath : NSIndexPath = iPath![0] as NSIndexPath 
    let rowIndex = indexPath.row 
    print("row index = \(rowIndex)") 
} 
+0

Diese Frage hat bereits eine akzeptierte Antwort. – dfd

Verwandte Themen