Swift : prepareForSegue with navigation controller

In prepareForSegue access the target navigation controller, and then its top:

let destinationNavigationController = segue.destination as! UINavigationController
let targetController = destinationNavigationController.topViewController

From the target controller you can access its view and pass data.

In old - now obsolete - versions of Swift and UIKit the code was slightly different:

let destinationNavigationController = segue.destinationViewController as UINavigationController
let targetController = destinationNavigationController.topViewController

  1. Prepare the segue in the SendViewController

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if segue.identifier == "segueShowNavigation" {
            if let destVC = segue.destination as? UINavigationController,
                let targetController = destVC.topViewController as? ReceiveViewController {
                targetController.data = "hello from ReceiveVC !"
            }
        }
    }
    
  2. Edit the identifier segue to "showNavigationController"

screenshot

  1. In your ReceiveViewController add

this

var data : String = ""

override func viewDidLoad() {
    super.viewDidLoad()
    print("data from ReceiveViewController is \(data)")
}

Of course you can send any other type of data (int, Bool, JSON ...)


Complete answer using optional binding and Swift 3 & 4:

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if let navigationVC = segue.destination as? UINavigationController, let myViewController = navigationVC.topViewController as? MyViewControllerClass {
        myViewController.yourProperty = myProperty
    }
}