How do you use IBSegueAction with navigation controller?

I've been trying to incorporate the new segue action functionality to communicate data between two view controllers. Unfortunately, the destination view controller is wrapped in a UINavigationController, which means that I have to return a UINavigationController. I've tried several different ways to pass data through the Navigation Controller to the root view controller(destination VC):


- use the segue identifer and/or the sender to get the navigation controller's root VC and set the data manually

- trying to access the destination VC directly

- create an instance of a nav controller, set the root VC to an instance of the destination VC


If you've figured this out, I would appreciate some insight on how you did it! Thanks.

Replies

Should do something like this:


override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    var destinationViewController = segue.destination
    if let navigationController = destinationViewController as? UINavigationController {
        destinationViewController = navigationController.visibleViewController ?? destinationViewController
    }



Could look at Stanford course CS193 for a detailed explanation.

h ttps://web.stanford.edu/class/cs193p/Winter2017/L6FaceIt.zip

@claude31: you didn't read the question.


@realli15: I've got this working, but it might not be the best solution.


You have two segues here: one which presents the UINavigationController, and another which sets the root ViewController inside the UINavigationController - so I pass the data through both segues, using a custom UINavigationController.


In my case, I have three ViewControllers:

- MainViewController (extends UIViewController)

- SettingsNavigationController (extends UINavigationController)

- SettingsViewController (extends UIViewController)


I want to create a SettingsViewModel in the MainViewController, and pass it through to the SettingsViewController.


So I first pass it into SettingsNavigationController, using an @IBSegueAction in MainViewController. This creates SettingsNavigationController, passing in the SettingsViewModel, which is stored in a property. The "present navigation controller" segue is wired up to this instantiation function.


Then I also have an @IBSegueAction in SettingsNavigationController, which makes the SettingsViewController, passing in the stored SettingsViewModel. The "set root viewcontroller" segue is wired up to this instantiation function.


Hope that helps :-)

Excuse me, I just replied to:

Unfortunately, the destination view controller is wrapped in a UINavigationController, which means that I have to return a UINavigationController.


Now, if the point is to find how to use IBAction instead, I would try by:

- subclassing navigationController

- in order to create :


@IBSegueAction
private func showPreview(coder: NSCoder)
    ->MyNavController? {
    MyNavController(coder: coder, param: param)
}


Then segue in the init of MyNavController

init(coder: coder, param: param)


I am not sure I can see the value of this.

Note: read this : h ttps://useyourloaf.com/blog/better-storyboards-with-xcode-11/

It sounds as if I'm having the same problem as you. I asked this question on StackOverflow… https://stackoverflow.com/questions/58545313/using-ibsegueaction-with-uinavigationcontroller

I answered it here: https://stackoverflow.com/a/60085063/259521