Pass Information Back to the Previous View Controller. Example in Swift.

In one of my previous blog posts I have shared with you how to send information forward from one view controller to another. If you have missed it please click on the link above to read it. In this blog post I am going to share with you how to pass data back to the previous view controller.

So let’s assume you have two view controllers: FirstViewController and SecondViewController. User navigates from FirstViewController to the SecondViewController. SecondViewController will process some business logic and the result of that business logic will need to be send back to the FirstViewContoller when user navigates back. To do that we will do the following:

In your FirstViewContoller create a new property which will hold the value sent from SecondViewController. Like so:

 class ViewController: UIViewController {
    var valueSentFromSecondViewController:String?
}

Next, in our SecondViewController we will create a Protocol with the help of which we will pass the data.  We will call this protocol “MyProtocol” and will define one function in it which will accepts one parameter.  We will also create a variable of type MyProtocol which will be accessed from FirstViewController. So our SecondViewController will now look like this:

protocol MyProtocol {
    func setResultOfBusinessLogic(valueSent: String)
}

class SecondViewController: UIViewController { 
 
  var delegate:MyProtocol?

  override func viewWillAppear(animated: Bool) {
        super.viewWillAppear(animated)
   }
}

Next, we will add some business logic that needs to be performed inside of viewWillAppear function and the result of it will be sent as an argument to setResultOfBusinessLogic function. So our SecondViewController will not look like this:

protocol MyProtocol {
    func setResultOfBusinessLogic(valueSent: String)
}

class SecondViewController: UIViewController { 
 
  var delegate:MyProtocol?

  override func viewWillAppear(animated: Bool) {
        super.viewWillAppear(animated)

        // Perform some business logic. Anything! 
        let firstName = "Sergey"
        let lastName = "Kargopolov"
        let fullName = firstName + " " + lastName 
      
        delegate.setResultOfBusinessLogic(fullName)
   }
}

We are not done with our SecondViewController. When user taps on back button and navigates to FirstViewController we need to display value produced in SecondViewController. To do that we need to:

  1. Make our FirstViewController to conform to a protocol we created: MyProtocol
  2. Declare a new variable valueSendFromSecondViewController
  3. Add viewWillAppear function to display valueSendFromSecondViewController
  4. Implement MyProtocol’s function setResultOfBusinessLogic
 class FirstViewController: UIViewController, MyProtocol { 
     
     // 1. Declare a new variable to hold data sent from SecondViewController
     var valueSentFromSecondViewController:String? 

     // 2. Add viewWillAppear to display the value of the variable 
     override func viewWillAppear(animated: Bool) {
        super.viewWillAppear(animated)

      // 3. Before displaying the value check if it contains data  
        if let valueToDisplay = valueSentFromSecondViewController:String
        {
           print("Value from display = \(valueToDisplay)")
        }
   }

    //4. Implement MyProtocol's function to make FirstViewContoller conform to MyProtocol 
    // MARK: MyProtocol functions
    func setValueFromDisplay(valueSent: String)
    {
        self.valueSentFromDisplay = valueSent
    }

 }

We are almost done here. The only thing that remains to be done is to set to an instance of SecondViewController a delegate. We will do it at the time we instantiate SecondViewController and present it to the user. Let’s assume that user is taken to the SecondViewController when they tap on a button and a goNext() function is called. Let’s create goNext function and add to it code that will instantiate SecondViewController and will present it to user.

class FirstViewController: UIViewController, MyProtocol { 
     
     // 1. Declare a new variable to hold data sent from SecondViewController
     var valueSentFromSecondViewController:String? 

     // 2. Add viewWillAppear to display the value of the variable 
     override func viewWillAppear(animated: Bool) {
        super.viewWillAppear(animated)

     // 3. Before displaying the value check if it contains data  
     if let valueToDisplay = valueSentFromSecondViewController:String
     {
           print("Value from display = \(valueToDisplay)")
     }
   }
    //4. Implement MyProtocol's function to make FirstViewContoller conform to MyProtocol 
    // MARK: MyProtocol functions
    func setValueFromDisplay(valueSent: String)
    {
        self.valueSentFromDisplay = valueSent
    }


   @IBAction func goNext(sender: AnyObject)
    {
        // 1. Instantiate SecondViewController
        let secondViewController = self.storyboard?.instantiateViewControllerWithIdentifier("SecondViewController") as! SecondViewController
       // 2. Set self as a value to delegate         
       secondViewController.delegate = self
       
       // 3. Push SecondViewController  
       self.navigationController?.pushViewController(secondViewController, animated: true)
    }


} // End of FirstViewController

This should be it! Having this example you should be able to pass data back to the previous view controller.

In this video tutorial I will demonstrate how to send data back from a view controller that loads a web page to a view controller that displays and updates a TableView with an information passed from a second view controller.

I hope this blog post was of some value to you. Please comment below if you have questions.

Happy learning!

  • bfalling

    Nice example. It might be worth mentioning that this is the Delegate Pattern, one of the core Cocoa design patterns.

    • Very good point! Thank you very much!

  • Roel Spruit

    Since the delegate property of the SecondViewController is an optional, this line will cause an error: delegate.setResultOfBusinessLogic(fullName). Instead unwrap the optional before using it:

    if let del = delegate {
    del.setResultOfBusinessLogic(fullName)
    }

    of use optional chaining to do it in one go: delegate?.setResultOfBusinessLogic(fullName)

  • Rodrigo Vieira

    Can i use the NSNotificationCenter to pass informations between classes?

    • Clément Sauvage

      Sure you can, but globally the accepted pattern is delegation

      Concerning datas
      – Passing forward, you should use `prepareForSegue`
      – Passing backward, you should use delegation
      – Passing to multiple things (VC, M…) : use `NSNotificationCenter`

  • Daryl Wong

    So I have just gone through the 3 related youtube tutorials. Do you have the project files that I can download?

  • VotaNO

    Great Tutorial. THANKS!!

  • Mark

    This is super helpful. Thank you so much!

  • Max

    Good stuff