Passing data back and forward between view controllers

I will go straight to the point and tell you how to send data back and forward in different situations.

This code was written in Swift 3

Sending data forward using Segue

If you are navigating from ViewControllerA to ViewControllerB using Segue called “toViewControllerB” then do the following steps

1- In ViewControllerB declare a variable to store the incoming data from ViewControllerA by adding the following code just before viewDidLoad()

var selectedItem : String?

2- Still in ViewControllerB print the value of “selectedItem” by add this code in viewDidLoad()

print(selectedItem!)

3- In ViewControllerA uncomment that function or add it if it does not exist:

override func prepare(for segue: UIStoryboardSegue, sender: Any?)

This function will run every time a segue is about to be performed

4- Add the following code to prepare for segue function and press run

        //first check for our segue using its idenifier
        if segue.identifier == "toViewControllerB" {
            
            //get reference to our destination view controller
            let secondView = segue.destination as! ViewControllerB
            
            //pass our data to the variable on the destination view controller
            secondView.selectedItem = "Milk"
        }

after navigating to ViewControllerB you should see “Milk” printed in the console

Sending data forward to programmatically presented view controller

If you are not using segue then just do the following to present the second view controller and pass data to it.

Don’t forget to set “Storyboard ID” for you view controller in “identity inspector”.

let sb = UIStoryboard.init(name: "Main", bundle: Bundle.main)
let secondView = sb.instantiateViewController(withIdentifier: "ViewControllerB") as! ViewControllerB
secondView.selectedItem = "Eggs"
self.present(secondView, animated: true, completion: nil)

Hit run and you should see “Eggs” printed in Xcode console.

Send data back using delegate

First of all ViewControllerA should be ViewControllerB’s delegate so that we can pass data to it.

1- Therefore in ViewControllerB create a protocol before the Class  and after the import UIKit line

protocol ViewControllerBDelegate : class {
    
    func getDataBack(info : String) -> ()
}

2- Still in ViewControllerB create a weak property of that delegate before viewDidLoad

weak var delegate : ViewControllerBDelegate?

It must be weak so that we don’t create strong reference cycles.

3- In ViewControllerA add ViewControllerBDelegate protocol in class declaration like that

class ViewControllerA: UIViewController, ViewControllerBDelegate {

4- Make the ViewControllerA conforms to the protocol by implementing the protocol function in ViewControllerA

func getDataBack(info: String) {
    print(info)
}

5- Before presenting ViewControllerB set ViewControllerA as its delegate.

if you are using segue

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {

//first check for our segue using its idenifier

if segue.identifier == "toViewControllerB" {

//get reference to our destination view controller

let secondView = segue.destination as! ViewControllerB

//set me as destination delegate

secondView.delegate = self

}

}

otherwise if you are presenting it programmatically

let sb = UIStoryboard.init(name: "Main", bundle: Bundle.main)
let secondView = sb.instantiateViewController(withIdentifier: "ViewControllerB") as! ViewControllerB
secondView.delegate = self
self.present(secondView, animated: true, completion: nil)

6- Finally go to ViewControllerB and just before going back send the data you want to the view controller’s delegate

@IBAction func goBack(_ sender: UIButton) {
        
    self.delegate?.getDataBack(info: "Cheese")
        
    self.dismiss(animated: true, completion: nil)
}

Please tell me if you have any questions

You might like Using InOut parameters in Swift

Leave a Reply

Your email address will not be published. Required fields are marked *