3
votes

I would like to select one cell in my TableViewController. The text of the cell should be transferred via segue to FirstViewController's label. I always get the error shown below.

The identifier is correct.

My code:

override func prepareForSegue(segue: UIStoryboardSegue!, sender: AnyObject!) {
    if (segue.identifier == "BackToCalculator") {
        //let myRow = tableView.indexPathForSelectedRow().row+1
        let vc = segue.destinationViewController as FirstViewController
        vc.SelectedBundesland.text = "Test"
    }
}

Exception:

0x103f1f5dc: jne 0x103f1f5d0 ; swift_dynamicCastClassUnconditional + 48 0x103f1f5de: leaq 0x3364d(%rip), %rax ; "Swift dynamic cast failed" 0x103f1f5e5: movq %rax, 0xa456c(%rip) ; gCRAnnotations + 8 0x103f1f5ec: int3
0x103f1f5ed: movq %r14, %rax

What is wrong?

5
Maybe the problem is that the destination view controller is not an instance of FirstViewController - have you checked that? Which is the line raising the exception?Antonio
Can you tell me how to implement that the DestinationViewController is an instance of FirstViewController? I am new to Swift. Thanks in advanceVelocity
That's more about iOS development than swift - my guess is that you don't even know how to do that in objective-c. So I suggest to read some documentation, and read some tutorials, such as this, and others available at the raywenderlich website - or just google.Antonio
In Objective C i added the DestVC.h into FirstVC.h. But this is not necessary anymore. Is there a way like this in swift?Velocity
No you don't need to do that in swift. Remove the as FirstViewController cast, put a breakpoint in the next line and check what's the actual type of vc - I think that to do that you have to comment the vc.SelectedBunesland.text = "Test" line out.Antonio

5 Answers

2
votes

May be late in the game but was getting the exact same issue. The problem here was your Segue was pointing to the Tab controller rather than the actual ViewController where it needs to jump to. I am referring to the 2nd screenshot you have provided to Antonio. If you fix that it should work fine.

2
votes

A much safer and forward approach is conditional cast, or even better protocol based, consider the following:

override func prepareForSegue(segue: UIStoryboardSegue!, sender: AnyObject!) {
    if let vc = segue.destinationViewController as? FirstViewController {
        vc.SelectedBundesland.text = "Test"
    } else {
       print("Some other controller! \(segue.destinationViewController)")
    }
}

That certainly works. But if you have multiple segues and multiple viewController it can be quite a pain to swing information and data around.

Consider the protocol approach:

protocol BundeslandProtocol {
    var SelectedBundesland: String {get set}
}

override func prepareForSegue(segue: UIStoryboardSegue!, sender: AnyObject!) {
    if var vc = segue.destinationViewController as? BundeslandProtocol {
        vc.SelectedBundesland.text = "Test"
    }
}

To make the above work you just have to declare your UIViewController to conform to said protocol:

class AwesomeViewController: UIViewController, BundeslandProtocol {
 .... 
}

Over time you'll be able to rename your classes, change them, replace and expand your project and you won't have to care about changing references around, as long as the protocol will keep its purpose.

It's not easy to tell where your code is broken: it usually happen when you forget to set your class name (FirstViewController in your case) in the storyboard, for the controller to which the segue is executed, see screenshot, it has to be set instead of UIViewController generic class.

see screenshot

1
votes

I have had a similar error - I believe that segue.destinationViewController is here a UINavigationController. You are getting an error because you are trying to cast a UINavigationController into your FirstViewController class.

Change this line: let vc = segue.destinationViewController as FirstViewController

to this: let vc = segue.destinationViewController.topViewController as FirstViewController

.topViewController is the top view controller on the navigation stack - which should now be an instance of FirstViewController

0
votes

Check your storyboard,I think you make the segue "point" to another viewController by mistake.

0
votes

Try this,

self.performSegueWithIdentifier("BackToCalculator", sender: self)

override func prepareForSegue(segue: UIStoryboardSegue!, sender: AnyObject!) {

    if (segue.identifier == "BackToCalculator") {
        //let myRow = tableView.indexPathForSelectedRow().row+1
        let vc = segue.destinationViewController as FirstViewController
        vc.SelectedBundesland.text = "Test"
}

U need to call self.performSegueWithIdentifier.