Search code examples
iosswiftsegue

different viewcontroller segue


I want to my app can "auto" segue from ViewControll A to b, and b to c,(a,b,c is independent viewcontroller), so I did :

  1. defined a timer at A_ViewController, can segue from A to B to C each one minute.

  2. set segue at on storyBoard for ViewController A and B:

    A_ViewController : 'goToB' and 'goToC'

    B_ViewController : 'goToC'

  3. and overwrite "overwrite func prepare(for segue:....." in A_ViewController.

Code:

class A_ViewController:  ViewController {

    ...//in Timer
       //first 1 minute
       performSegueWithIdentifier("goToB", sender: self)
       //second minute
       B_Controller(). goToC()
    ...

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if segue.identifier == "goToB" {
            let B_Controller = segue.destination as! B_ViewController
            B_ViewController.msg = "From AtoB"
        }
        if segue.identifier == "goToSearchLocation" {
            let C_ViewController = segue.destination as! C_ViewController
            C_ViewController.msg = searchWord
            }
    }

class B_Controller:  ViewController {
    ...
    func goToC() {
       performSegueWithIdentifier("goToC", sender: self)
    }
}

After run APP, first segue can done(Show ViewController B successfully), but after that, it always shows the error message as below :

Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Receiver () has no segue with identifier 'goToC''

But I really set a segue 'goToC' on storyBoard. I do not know how to fix it. The code is already I modified from google search.


Solution

  • When you say B_Controller().goToC() you are creating a new instance of B_Controller, you aren't referring to the existing instance that was created by the goToB segue. Further, since your new instance of B_Controller isn't being created from the storyboard, it doesn't know anything about segues.

    You need to store a reference to the instance of B_Controller that you are presenting in a property. Then you can use that property to invoke the goToC function.

    class A_ViewController:  ViewController {
    
        var bController: B_Controller?
    
        ...//in Timer
           //first 1 minute
           performSegueWithIdentifier("goToB", sender: self)
           //second minute
           self.bController?.goToC()
        ...
    
        override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
            if segue.identifier == "goToB" {
                self.bController = segue.destination as! B_ViewController
                self.bController.msg = "From AtoB"
            }
            if segue.identifier == "goToSearchLocation" {
                let C_ViewController = segue.destination as! C_ViewController
                C_ViewController.msg = searchWord
                }
        }
    
    class B_Controller:  ViewController {
        ...
        func goToC() {
           performSegueWithIdentifier("goToC", sender: self)
        }
    }
    

    You might want to re-design your code though; It would probably be cleaner to have a new timer in B that presents C rather than trying to use a single timer in A.