A. Petrizza
A. Petrizza

Reputation: 3350

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?

Upvotes: 0

Views: 200

Answers (2)

Danh Huynh
Danh Huynh

Reputation: 2327

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
        }
    }
}

Upvotes: 2

picciano
picciano

Reputation: 22701

You should be setting the advertisement variable in a prepare(for:sender:) function. The view controller that you are creating in the didSelect function is not being used.

Add something like this:

func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if let viewController = segue.destination as? PlayerViewController {
        let adChoice = adArray[sender]
        viewController.advertisement = sender as? STZMediaItem
    }
}

And update your didSelect function to be:

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

Upvotes: 1

Related Questions