1

I have created the model class and with some static images and text I have populated the UICollectionView, but when the user touches the cell it shows an error in view controller 2 when I print or show it on a label. Below is the code.

Any suggestion?!

This is the model class

import Foundation

class Pokemon {
    private var  _name: String!
    private var _pokedexId: Int!

    // Setter And Getter
    var name : String {
        return _name
    }

    var pokedexId: Int {
        return _pokedexId
    }

    // Initializer to initialize the data
    init(name : String, pokedexId: Int) {
        self._name = name
        self._pokedexId = pokedexId
    }
}

This is segue func in viewcontroller 1

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "pokeSegue" {
    if let detailVC = segue.destinationViewController as? ViewController2 {
        if let poke = sender as? Pokemon {
            detailVC.pokemon = poke
        }
    }
}

UICollectionView delegate

    func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) {
    let poke: Pokemon!
    if inSearchMode {
        poke = filteredPokemon[indexPath.row]
    } else  {
        poke = pokemon[indexPath.row]
    }
    print(poke.name)
    performSegueWithIdentifier("pokeSegue", sender: self)
}

In viewController2

import UIKit
class ViewController2: UIViewController {

    var pokemon: Pokemon!
    var receviceingString : String!

    @IBOutlet weak var label: UILabel!

    override func viewDidLoad() {

      print(pokemon.name) //unexpectedly found nil while unwrapping an Optional value
    }

} 
Matthew Hallatt
  • 1,310
  • 12
  • 24
kk002able
  • 63
  • 9
  • 1
    Hint: sender is not a Pokemon but a type of UIView. – Raphaël Mar 07 '16 at 09:57
  • @Raphael Sir thank you for your rlp but can you elaborate becoz Pokemon name is a class – kk002able Mar 07 '16 at 10:01
  • The test `let poke = sender as? Pokemon` is always `false` because the `sender` argument of `prepareForSegue` is the UIView / control that triggered the segue. – Raphaël Mar 07 '16 at 10:02
  • Print the sender in `prepareForSegue` to see the type. As Raphaël hinted it's probably not a `Pokemon` object. Side-note: what tutorial suggests those stupid backing private variables to create read-only properties? In Swift just declare a property as constant (let) to get the same functionality and get rid of the private variables. – vadian Mar 07 '16 at 10:16
  • @vadian Sir its printing the correct value which i want to pass it to the viewcontroller2 but as soon as the viewcontroler2 is loaded it give the fatal error Any Suggestion..!! – kk002able Mar 07 '16 at 10:20
  • @kk002able Put a breakpoint in `prepareForSegue` and see step by step what is happening and what value is given to `detailVC.pokemon`. – Raphaël Mar 07 '16 at 10:36
  • @raphael Sir As you have said the line ie let poke = sender as?Pokemon returning false but cannot figure it out how to solve.. – kk002able Mar 07 '16 at 10:41
  • I have perform the segue in "didSelectItemAtIndexPath" and tried to print the required value which i want to send and it prints the correct one and further in prepare for segue i tried to send but error is what am i getting when second view is loaded – kk002able Mar 07 '16 at 10:42
  • Can you add the code of this method to your question ? – Raphaël Mar 07 '16 at 10:44
  • If `as? Pokemon` returns false then *it's **not** printing the correct value* – vadian Mar 07 '16 at 10:44

1 Answers1

3

EDIT

Use poke as the sender instead of self when calling performSegueWithIdentifier :

performSegueWithIdentifier("pokeSegue", sender: poke)

ORIGINAL ANSWER

I assume that you are using an UICollectionViewCell to trigger the segue.

If so, the let poke = sender as? Pokemon will always returns false and be skipped because the sender will be the UICollectionViewCell that triggered the segue and not an instance of Pokemon.

You can either create a new type of UICollectionViewCell that can store a Pokemon object or simply use the tag property of the cells to store the index of the referenced Pokemon.

This value is configurable from the collectionView(_ collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) method.

Then in the prepareForSegue method you have to cast the sender object to the relevant UICollectionView type and retrieve the Pokemon with the information you defined.

Raphaël
  • 3,646
  • 27
  • 28