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

        Hi,

            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 (6,075 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

           

          ------------

          EDITED

          -----------

          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() {
                  super.viewDidLoad()
              }
             
              @IBAction func writeToVC2(_ sender: UIButton) {
                 
                  let text = textToWrite.text
                  if let vc2 = self.navigationController?.viewControllers[1] as? ViewController2 {
                     vc2.labelToSetInVC2.text = text
                  }
               }
             
          }