Access the instance of a Viewcontroller from another in swift Access the instance of a Viewcontroller from another in swift ios ios

Access the instance of a Viewcontroller from another in swift


1. If the view controller containing the textfield can call (with a segue) the view controller containing the label...

Add a new Cocoa Touch class file in your project, name it FirstViewController and set the following code in it:

import UIKitclass FirstViewController: UIViewController {        @IBOutlet weak var textField: UITextField! // FIXME: link this to the UITextField in the Storyboard!!!        override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {        let controller = segue.destinationViewController as! SecondViewController        controller.text = textField.text    }    }

Add a new Cocoa Touch class file in your project, name it SecondViewController and set the following code in it:

import UIKitclass SecondViewController: UIViewController {        var text: String?    @IBOutlet weak var label: UILabel! // FIXME: link this to the UILabel in the Storyboard!!!        override func viewDidLoad() {        super.viewDidLoad()                label.text = text    }    }

In the Storyboard, embed the first view controller in a UINavigationController. Link the first view controller to the second with a UIButton or a UIBarButtonItem. Set the name of the first view controller to FirstViewController and the name of the second view controller to SecondViewController. Create a UITextField in the first view controller. Create a UILabel in the second view controller. Link the textfield and the label to their respective declarations in FirstViewController and SecondViewController.


2. If the view controller containing the label can call (with a segue) the view controller containing the textfield...

Here, this is a perfect protocol/delegate case. You may find a lot of stuff on StackOverflow dealing with this. However, here is a rough example.

Add a new Cocoa Touch class file in your project, name it FirstViewController and set the following code in it:

import UIKitclass FirstViewController: UIViewController, DetailsDelegate {        @IBOutlet weak var label: UILabel! // FIXME: link this to the UILabel in the Storyboard        func updateLabel(withString string: String?) {        label.text = string    }        override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {        let controller = segue.destinationViewController as! SecondViewController        controller.delegate = self    }    }

Add a new Cocoa/Cocoa Touch class file in your project, name it SecondViewController and set the following code in it:

import UIKitprotocol DetailsDelegate: class {    func updateLabel(withString string: String?)}class SecondViewController: UIViewController {        weak var delegate: DetailsDelegate?    @IBOutlet weak var textField: UITextField! // FIXME: link this to the UITextField in the Storyboard        override func viewWillDisappear(animated: Bool) {        super.viewWillDisappear(animated)                delegate?.updateLabel(withString: textField.text)    }}

In the Storyboard, embed the first view controller in a UINavigationController. Link the first view controller to the second with a UIButton or a UIBarButtonItem. Set the name of the first view controller to FirstViewController and the name of the second view controller to SecondViewController. Create a UILabel in the first view controller. Create a UITextField in the second view controller. Link the textfield and the label to their respective declarations in FirstViewController and SecondViewController.


Imanou Petit and Oscar Swanros already answered correctly. However there is an alternative which is rather "hacky" that I had to use to transfer data between 2 view controllers without a segue connecting them.

To obtain the root view controller of your app you can do:

UIApplication.sharedApplication().windows[0].rootViewController

From there you can get any view controller you want. For instance, if you want the second child view controller of the root view controller then you would do:

let viewController = UIApplication.sharedApplication().windows[0].rootViewController?.childViewControllers[1] as? YourViewControllerviewController?.yourProperty = newValue

Keep in mind that this approach is rather "hacky" and probably violates the best coding practices.


You need to create a Segue between View Controllers:

  1. On your Storyboard, select ViewController A.
  2. While holding the Control, click ViewController A, drag and drop the blue line to ViewController B. If ViewController A is embedded in a NavigationController, select "show" from the menu that appears when you let go. Otherwise, select "present modally."
  3. Select the Segue on your Storyboard, and on the Utilities Panel, go to the Attributes Inspector and assign an Identifier for your segue (e.g.: "DetailSegue").

Now, when you want to trigger the segue on ViewController A, you just need to call (maybe on the tap of a button):

@IBAction func buttonTapped() {    self.performSegueWithIdentifier("DetailSegue", sender: self)}

To pass a value to ViewController B, override the prepareForSegue:sender method on ViewController A:

override func prepareForSegue(segue: UIStoryboardSegue!, sender: AnyObject!) {    if segue.identifier == "DetailSegue" {        var viewControllerB = segue.destinationViewController as ViewControllerB        viewControllerB.text = self.textField.text    }}

Pretty straightforward.

Note that for this to work, your ViewController B class should look something like this:

class ViewControllerB: UIViewController {    ver label = UILabel(...)    var text: String?     override func viewDidLoad() {        super.viewDidLoad()        label.text = text!    }}

Hope this helps.