Search code examples
iosswiftuicollectionviewsegueuistoryboardsegue

CollectionView Segue finding nil on receiving ViewController


I have a collection view that is selecting an Item in its index and performing a segue to the next ViewController. When the next ViewController is presented, the value of my object is nil.

Here is the call in the collectionView:

func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
    guard let adViewVC = storyboard?.instantiateViewController(withIdentifier: adViewPageID) as? AdViewPageVC else {return}
    let adChoice = adArray[indexPath.row]
    adViewVC.advertisement = adChoice
    performSegue(withIdentifier: adViewPageSegue, sender: self)
}

Note that the guard statement is going through and if I print a value from the adArray it has value in this function.

After I perform the segue which does open the right ViewController the advertisement object is always nil.

var advertisement : Advertisement!

override func viewDidLoad() {
    super.viewDidLoad()

    let title = advertisement.title
    print(title)

}

This is never getting the value of the object even when I can see that it has value during the assignment on the didSelectItem function for the collection view.

What am I missing here?


Solution

  • When the user taps on the collectionViewCell, the app should perform segue with an indexPath as a sender:

    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
        performSegue(withIdentifier: adViewPageSegue, sender: indexPath)
    }
    

    And prepare all of neccessary things in the prepare(for:sender:) method. And you don't have to init a viewController from the storyboard. segue.destination is enough.

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if let identifier = segue.identifier {
            if identifier == adViewPageSegue {
                guard let adViewVC = segue.destination as? AdViewPageVC else {return}
                let indexPath = sender as! IndexPath
                let adChoice = adArray[indexPath.row]
                adViewVC.advertisement = adChoice
            }
        }
    }