prepareForSegue collectionView indexPath using swift

SKYnine picture SKYnine · Nov 13, 2014 · Viewed 10.5k times · Source

I don't find any good example to do what I want using swift so I allow myself to ask the question.

Im using a collectionView to display PFObjects and I want to send the displayed cell data to a second controller using prepareForSegue.

At this point, Im struggling to make this part of the code works:

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
        if(segue.identifier == "goto_answerquestion"){
            var indexpath : NSIndexPath = self.collectionView.indexPathsForSelectedItems()
        }
    }

this line:

var indexpath : NSIndexPath = self.collectionView.indexPathsForSelectedItems()

triggers the following error:

(UICollectionView, numberOfItemsInSection: Int)-> Int does not have a member named 'indexPathsForSelectedItems'

please let me know if Im using the wrong method, or if you need additional data to have the appropriate overview of the problem.

ANSWER

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
        if(segue.identifier == "segue_identifier"){
            // check for / catch all visible cell(s)
            for item in self.collectionView!.visibleCells() as [UICollectionViewCell] {
                var indexpath : NSIndexPath = self.collectionView.indexPathForCell(item as CollectionViewCell)!
                var cell : CollectionViewCell = self.collectionView!.cellForItemAtIndexPath(indexpath) as CollectionViewCell

                // Grab related PFObject
                var objectData:PFObject = self.questionData.objectAtIndex(indexpath.row) as PFObject

                // Pass PFObject to second ViewController
                let theDestination = (segue.destinationViewController as answerPageViewController)
                theDestination.questionObject = objectData
            }
        }
    }

Answer

BJ Miller picture BJ Miller · Nov 13, 2014

If you just are trying to just find the index path of the cell tapped, and not have multiple, you could do this in your prepareForSegue method:

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
    let indexPath = collectionView.indexPathForCell(sender as UICollectionViewCell)
    // do what you need now with the indexPath
}

sender in this situation is the cell you tapped, so you just need to cast it to UICollectionViewCell (or a custom cell subclass, if you made one).

UPDATE:
Swift 1.2 introduced as! to replace as for this purpose, so to keep with safety, you can try this inside prepareForSegue using multiple bindings:

if let cell = sender as? UICollectionViewCell, indexPath = collectionView.indexPathForCell(cell) {
    // use indexPath
}