isaacthedev
isaacthedev

Reputation: 201

How to present data on a view controller, based on the cell that was tapped in the previous controller

I have View Controller A, which has five static collection view cells, with a title label, and a description label. Based on which cell was tapped, I need to segue to View Controller B, and View Controller B will present a list of products associated with that data.

I attempted to do this is didSelect method, but I think I am wrong... I realized after using print statements I am correctly getting the navigation to work, and I can also print the name label on View Controller A, but the data passed to View Controller B is nil.

View Controller A

var parameters: [Parameter] = [ Parameter(name: "Alkalinity", description: "A description here is about how important it is to have a stable measurement"), Parameter(name: "Calcium", description: "A description here is about how important it is to have a stable measurement"), // Cut the amount so I do not take too much space here ]

override func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
   let selectedCell = parameters[indexPath.row]
    // Create an instance of DeatailViewController and pass that variable
    let destinationVC = DetailViewController()
    destinationVC.dataReceived = selectedCell.name
    self.performSegue(withIdentifier: "segueID", sender: self)

}

View Controller B

only a print statement.

Expected: Pass the name of the cell I tapped to the second VC, (For now) but I want to show a list of products associated with each element in name label. ex: Alkalinity will show Alkalinity products ( should I define this in the same of different model)?

Error: Showing nil on VCB

Suggestions:

Maybe using index path in didSelectRow?

Upvotes: 1

Views: 127

Answers (2)

Shehata Gamal
Shehata Gamal

Reputation: 100503

When using a segue to pass data you need to implement prepareForSegue

override func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { 
    self.performSegue(withIdentifier: "segueID", sender:parameters[indexPath.row]) 
}

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if segue.identifier == "segueID" {
         let vc = segue.destination as! DetailViewController
         destinationVC.dataReceived = sender as! Model // Model is type of array parameters
    }
}

but with vc instantiation DetailViewController() you need to use present/push

let destinationVC = DetailViewController()
destinationVC.dataReceived = selectedCell.name
self.present(destinationVC,animated:true)

For second way presenting DetailViewController() will crash the app as you don't load the vc from storyboard , so it should be like

let vc = self.storyboard!.instantiateViewController(withIdentifier: "DetailID") as! DetailViewController

Upvotes: 1

mori_ahk
mori_ahk

Reputation: 101

If you are using segue, I would achieve that by doing something like this:

 override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if segue.identifier == "segueID" {
            if let destinationVC = segue.destination as? DetailViewController {
            destinationVC.dataReceived = selectedCell.name
            }
        }
}

Upvotes: 0

Related Questions