4 Replies
      Latest reply on Oct 4, 2018 12:19 AM by mksmurali
      mksmurali Level 1 Level 1 (0 points)


            I am having 4 ViewControllers and navigated to fourth viewcontroller by pushing from first to second and second to third and third to fourth.

        From fouth viewcontroller i need to pass a data to second viewcontroller.

        How to implement this?

        • Re: How to get Data in a Viewcontroller ?
          Claude31 Level 8 Level 8 (8,405 points)

          1. Delegation is a way to do it.


          Let's call your ViewControllers classes VC1, VC2, VC3, VC4.

          Imagine you want to pass a String to VC2, to update a UITextField


          One complexity is that you don't go directly from VC2 to VC4, but through VC3.


          Declare a protocol:

          protocol delegate_transferData {
              func writeInVC2(text: String)


          In VC4, you create a delegate property :

          I you want to send data when clicking a button:


          class VC4: UIViewController {
              var delegate: delegate_transferData?
              @IBAction func writeDataToVC2(_ sender: UIButton) {
                  let textToWrite = "I write this to VC2"
                  delegate?.writeInVC2(text: textToWrite)


          In VC2, you implement the delegate func and will pass the delegate reference ; because you don't go directly to VC4, you'll first pass this reference to VC3:


          class VC2: UIViewController, delegate_transferData {
              @IBOutlet weak var text1: UITextField!
              func writeInVC2(text: String) {
                  text1.text = text
              override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
                  if let destination = segue.destination as? VC3 {
                      destination.temporaryDelegate = self     // That's the complexity: to keep delegate in VC3 for use later in VC4

          And in VC3


          class VC3: UIViewController {
              var temporaryDelegate: delegate_transferData?
              override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
                  if let destination = segue.destination as? VC4 {
                      destination.delegate = temporaryDelegate     // Now we get VC2 as delegate in VC4



          2. Another way would be to declare at the global scope a var to store the data you want to transmit


          var dataToSend: String?


          And set it in VC4 and reuse in VC2





          3. A 3rd way, if you are in a NavigationController,

          use property of the navigationController

          var viewControllers: [UIViewController]


          When in VC4, calling viewControllers[1] gives a reference to VC2 ; then you can access any property of it (this works because Navigation controllers keeps the stack of VC you come from ; however, you could not use this method to write ahead fromVC1 to VC3 for instance).

          For instance, to copy a text from a UITectField in VC4 directly in VC2 when clicking the UIButton


          class ViewController4: UIViewController {
              @IBOutlet weak var textToWrite: UITextField!
              override func viewDidLoad() {
              @IBAction func writeToVC2(_ sender: UIButton) {
                  let text = textToWrite.text
                  if let vc2 = self.navigationController?.viewControllers[1] as? ViewController2 {
                     vc2.labelToSetInVC2.text = text