Search code examples
iosswiftxcode-storyboard

Prepare for segue: Cannot convert value of type 'UIViewController' to specified type 'SecondViewController'


I know I must be missing something obvious here, but I can't seem to reference a destination View Controller by it's actual type. I've created a new project from scratch to test this, following these steps:

  • Create a new Single-View Application project
  • Add a new View Controller
  • Create a new class, subclassing UIViewController, and called it SecondViewController
  • Set this new class as the Custom Class for the second View Controller (and its title is now Second View Controller)
  • Added a button to the first View Controller and ctrl-clicked from it to the second one, and selected Show from the Action Segue list
  • Added an 'id' property to SecondViewController
  • Added this code to the first View Controller:

    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) {
        let vc: SecondViewController = segue.destinationViewController
        vc.id = "test"
    }
    

Which results in an error of Cannot convert value of type 'UIViewController' to specified type 'SecondViewController'. I've tried everything I can think of, trying all the segue types etc, but am out of ideas. I know the segue itself is working as if I comment out that code it does indeed call the second View Controller (I even added a label to the designation just to be certain).

I'm new to Swift and Storyboard so it's probably something simple I'm missing here, but any help would be greatly appreciated!


Solution

  • You should be able to set the value like this.

    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) {
        if let vc: SecondViewController = segue.destinationViewController as? SecondViewController {
            vc.id = "test"
        }
    }
    

    This will be safer as well if you add other segues.

    Another way to do this would be to force cast the controller with

    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) {
        let vc: SecondViewController = segue.destinationViewController as! SecondViewController
        vc.id = "test"
    }
    

    This code should compile but it would crash if called with the wrong destinationViewController as opposed to the if let option which just wouldn't set the id value of the destination controller if it's not the intended class.