0

I have multiple UICollectionViews (4 to be precise) in the same ViewController. I made a containerview for every 'row' which consists of a Title and a UICollectionView. I made a Segue from every UICollectionViewCell to the details view controller and gave them an identifier. But I fail to understand how to get my Movie object from the containerview to the details page.

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if (segue.identifier == "MovieDetailsPlaying"){
        var destination = segue.destination as! DetailMovieController
        destination.item = containerNowPlayingView.movies[IndexPath]
    }
}

All I think I need to fix this problem is figure out how to get the IndexPath in the prepare function for the Segue in the ViewController. I hope you might be able to help me.

I already found answers like this: Answer one

My Segue's

2 of the 4 horizontal UICollectionViews

Ruben Aalders
  • 624
  • 6
  • 20

1 Answers1

1

Considering you didn't show what type of cell your using inside cellForItemAt indexPath I had to make some things up so this could become clear to you. I also don't know what you mean by you have 4 collection views but this is one of the ways you transfer data from a collectionViewCell to the destination view controller via prepareForSegue using 1 collectionView.

Inside preparForSegue you need 3 things:

1- you need to know the type of cell your using in cellForItemAt indexPath. For this example I used a cell class named MovieCell

2- you need to get the indexPath of the selected row. CollectionView has a method on it named indexPath(for:) that accepts a collectionViewCell as an arguement: collectionView.indexPath(for: UICollectionViewCell)

3- Get the information from the array corresponding to that selected row.

For an example you have a class named MovieDataModel with a movieName property:

class MovieDataModel{
    var movieName: String?
}

The collectionView cell is named MovieCell and it has a movieTitleLabel outlet in it:

class DetailedSearchComplaintCollectionCell: UICollectionViewCell {
    @IBOutlet weak var movieTitleLabel: UILabel!
}

Inside the class with your CollectionView:

@IBOutlet weak var collectionView: UICollectionView! // in this example there is only 1 collectionView
let movies = [MovieDataModel]() // an array of MovieDataModels

func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    return movies.count // return the number of items inside the movies array
}

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {

     let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "movieCell", for: indexPath) as! MovieCell // cast the cell as a MovieCell
     cell.movieTitleLabel.text = movies[indexPath.row].movieName! // this is the same info we need for the 3rd step

     return cell
}

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

    if (segue.identifier == "MovieDetailsPlaying"){

       // From the steps above
       let cell = sender as! MovieCell // 1- the same exact type of cell used in cellForItemAt indexPath. Access it using the sender parameter in the prepareFoeSegue signature and then cast it as a MovieCell
       let indexPath = collectionView.indexPath(for: cell) // 2- get the indexPath from the row that was tapped. Add the cell from step 1 as an argument to it. Notice it says collectionView because that's the name of the collectionView outlet. I'm not sure how this would work with 4 different collectionViews but you probably will have to make an indexPath for each one. Just an assumption

       var destination = segue.destination as! DetailMovieController
       destination.item = movies[indexPath!.row].movieName // 3- what MoviesDataModel item from inside the movies array and the title from it corresponds to the indexPath (the tapped row).
    }
}

I don't know the name of the collectionView cell your using but inside the class with the collectionView wherever you see the name MovieCell just change it to whatever the name of the cell is your using.

Lance Samaria
  • 17,576
  • 18
  • 108
  • 256
  • All I needed was this line `let indexPath = collectionView.indexPath(for: cell)`. Thank you very much :) – Ruben Aalders May 01 '18 at 10:26
  • I wasn’t sure of the level of skill you had so it was easier for me to spell everything out but yes you are correct that is what you needed and the line before that when you cast the cell. – Lance Samaria May 01 '18 at 12:04
  • Ah I see. Well I have developed a few Android commercial apps, but seem to struggle a lot with iOS development. Anyway, thanks a lot! – Ruben Aalders May 01 '18 at 12:30