One of my segues transitions from a view controller to a tableview controller. I want to pass an array between the two, but with a navigation controller before the tableview controller, I can't figure out how to pass the array. How do you pass data through a navigatiom controller to a tableview controller?
8 Answers
Override prepareForSegue
and set whatever value on the tableview you'd like. You can grab the tableview from the UINavigation
viewControllers
property.
override func prepareForSegue(segue: UIStoryboardSegue!, sender: AnyObject!){
let navVC = segue.destinationViewController as UINavigationController
let tableVC = navVC.viewControllers.first as YourTableViewControllerClass
tableVC.yourTableViewArray = localArrayValue
}
For Swift 3 :
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
let navVC = segue.destination as? UINavigationController
let tableVC = navVC?.viewControllers.first as! YourTableViewControllerClass
tableVC.yourTableViewArray = localArrayValue
}

- 921
- 1
- 10
- 28

- 13,441
- 3
- 48
- 75
-
21Instead of navVC.viewControllers.first, you can do navVC.topViewController – Arnaud Nov 28 '14 at 00:03
-
what if it is a view controller segue from the topViewController? – Jenita _Alice4Real Oct 20 '16 at 18:30
@Tommy Devoy's answer is correct but here is the same thing in swift 3
Updated Swift 3
// MARK: - Navigation
//In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
// Get the new view controller using segue.destinationViewController.
// Pass the selected object to the new view controller.
if segue.identifier == "yourSegueIdentifier" {
if let navController = segue.destination as? UINavigationController {
if let chidVC = navController.topViewController as? YourViewController {
//TODO: access here chid VC like childVC.yourTableViewArray = localArrayValue
}
}
}
}

- 1,243
- 1
- 14
- 24
I was getting this error to Horatio's solution.
ERROR: Value of type 'UINavigationController' has no member 'yourTableViewArray'
So this might help others like me looking for a code
only solution. I wanted to redirect to a Navigation controller, yet pass data to root view controller within that Nav Controller.
if let controller = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "yourNavigationControllerID") as? UINavigationController,
let yourViewController = controller.viewControllers.first as? YourViewController {
yourViewController.yourVariableName = "value"
self.window?.rootViewController = controller // if presented from AppDelegate
// present(controller, animated: true, completion: nil) // if presented from ViewController
}

- 3,143
- 1
- 32
- 42
-
1Perfecto solution, just to clarify, if presenting from AppDelegate, use self.window?.... and leave // present commented, if presenting from ViewController, comment // self.window?... and uncomment present(controller – Alejandro Luengo Jun 25 '17 at 17:53
-
1yes, because present() requires ViewController. Isn't it! But it has been some time since I am in touch with this. You can confirm by actually testing it out and probably leave a comment or suggest edit for the answer. I will update surely. – mythicalcoder Jun 25 '17 at 18:04
-
1Yes, it's ok, self.window?.rootViewController = controller if presented from AppDelegate and present(controller, animated: true, completion: nil) if presented from ViewController, just choose your case and comment the other one – Alejandro Luengo Jul 17 '17 at 11:34
SWIFT 3 (tested solution) - Passing data between VC - Segue with NavigationController
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
let navigationContoller = segue.destination as! UINavigationController
let receiverViewController = navigationContoller?.topViewController as ReceiverViewController
receiverViewController.reveivedObject = sentObject
}

- 540
- 1
- 8
- 21
Tommy's solution requires you to set up the Segue in Storyboard.
Here is a code only solution:
func functionToPassAsAction() {
var controller: UINavigationController
controller = self.storyboard?.instantiateViewControllerWithIdentifier("NavigationVCIdentifierFromStoryboard") as! UINavigationController
controller.yourTableViewArray = localArrayValue
self.presentViewController(controller, animated: true, completion: nil)
}
-
2ERROR: Value of type 'UINavigationController' has no member 'yourTableViewArray' !! (Using Swift3) – mythicalcoder Feb 16 '17 at 22:14
Swift 5
class MyNavigationController: UINavigationController {
var myData: String!
override func viewDidLoad() {
if let vc = self.topViewController as? MyViewcontoller{
vc.data = self.myData
}
}
}
let navigation = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "MyNavigationController") as! MyNavigationController
navigation.myData = "Data that you want to pass"
present(navigation, animated: true, completion: nil)

- 2,809
- 22
- 26
-
1the best solution for a code-only approach. didn't even know the `topViewController` property existed on a `navigation controller` – colin May 03 '21 at 07:12
FIXED syntax for SWIFT 3
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
let navVC = segue.destination as! UINavigationController
let tableVC = navVC.viewControllers.first as! YourTableViewControllerClass
tableVC.yourTableViewArray = localArrayValue
}

- 2,602
- 4
- 27
- 31
passing a text in tableview swift 4 **or just pass data but change the function **
First View Controller
class
let name_array = ["BILL GATES", "MARK ZUKERBERG", "DULKAR SALMAN", "TOVINO" , "SMITH"]
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath){
let story: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let new = story.instantiateViewController(withIdentifier: "SecondViewController")as! SecondViewController
new.str1 = name_array[indexPath.row]
self.navigationController?.pushViewController(new, animated: true)
Second View Controller
class SecondViewController: UIViewController {
@IBOutlet weak var lbl2: UILabel!
var str1 = String()
override func viewDidLoad() {
super.viewDidLoad()
lbl2.text = str1
}

- 99
- 5