How to call a function in the first controller after dismissing the second controller


I have two UIViewController, when I click a button, it goes from the first view controller to the second one. And before that, I animated a UIView to move to another place. After dismissing the second View Controller, I want to move the UIView in the first view controller back to where it originally was. However, when I call a function from the second View Controller to animate the UIview in the first view controller after dismissing the second one, It could not get the UIView's properties, and cannot do anything with it. I think because the first UIViewController is not loaded yet. Is that the problem? And How should I solve this?


There are two solutions you can either use swift closures

class FirstViewController: UIViewController { @IBAction func start(_ sender: Any) { guard let secondController = self.storyboard?.instantiateViewController(withIdentifier: "SecondController") as? SecondController else { return } secondController.callbackClosure = { [weak self] in print("Do your stuff") } self.navigationController?.pushViewController(secondController, animated: true) } } //---------------------------- class SecondController: UIViewController { var callbackClosure: ((Void) -> Void)? override func viewWillDisappear(_ animated: Bool) { callbackClosure?() } }

or you can use protocols

class FirstViewController: UIViewController { @IBAction func start(_ sender: Any) { guard let secondController = self.storyboard?.instantiateViewController(withIdentifier: "SecondController") as? SecondController else { return } secondController.delegate = self self.navigationController?.pushViewController(secondController, animated: true) } } extension ViewController : ViewControllerSecDelegate { func didBackButtonPressed(){ print("Do your stuff") } } //-------------------------- protocol SecondControllerDelegate : NSObjectProtocol { func didBackButtonPressed() } class SecondController: UIViewController { weak var delegate: SecondControllerDelegate? override func viewWillDisappear(_ animated: Bool) { delegate?.didBackButtonPressed() } }


You can try to use a closure. Something like this:

class FirstViewController: UIViewController { @IBOutlet weak var nextControllerButton: UIButton! private let animatableView: UIView = UIView() private func methodsForSomeAnimation() { /* perform some animation with 'animatableView' */ } @IBAction func nextControllerButtonAction() { // you can choose any other way to initialize controller :) let storyboard = UIStoryboard(name: "Main", bundle: nil) guard let secondController = storyboard.instantiateViewController(withIdentifier: "SecondViewController") as? SecondViewController else { return } secondController.callbackClosure = { [weak self] in self?.methodsForSomeAnimation() } present(secondController, animated: true, completion: nil) } } class SecondViewController: UIViewController { @IBOutlet weak var dismissButton: UIButton! var callbackClosure: ((Void) -> Void)? @IBAction func dismissButtonAction() { callbackClosure?() dismiss(animated: true, completion: nil) /* or you call 'callbackClosure' in dismiss completion dismiss(animated: true) { [weak self] in self?.callbackClosure?() } */ } }


When you present your second view controller you can pass an instance of the first view controller.

The second VC could hold an instance of the first VC like such:

weak var firstViewController: NameOfController?

then when your presenting the second VC make sure you set the value so it's not nil like so:

firstViewController = self

After you've done this you'll be able to access that viewControllers functions.


When you are saying it could not get the UIView's properties it's because you put it as private ? Why you don't replace your UIView in the first controller when it disappears before to go to your secondViewController. I think it's a case where you <strong>have to clean up your view controller state</strong> before to go further to your second view controller.

Check IOS lifecycle methods : <a href="https://developer.apple.com/documentation/uikit/uiviewcontroller/1621477-viewdiddisappear" rel="nofollow">viewWillDisappear</a> or <a href="https://developer.apple.com/documentation/uikit/uiviewcontroller/1621477-viewdiddisappear" rel="nofollow">viewDidDisappear</a> through Apple documentation and just do your animation in one of these methods.


iOS 11.x Swift 4.0

In calling VC you put this code ...

private struct Constants { static let ScannerViewController = "Scan VC" } override func prepare(for segue: UIStoryboardSegue, sender: Any?) { if segue.identifier == Constants.ScannerViewController { let svc = destination as? ScannerViewController svc?.firstViewController = self } }

Where you have named the segue in my case "Scan VC", this is what it looks like in Xcode panel.

<a href="https://i.stack.imgur.com/VdyKy.png" rel="nofollow"><img alt="enter image description here" class="b-lazy" data-src="https://i.stack.imgur.com/VdyKy.png" data-original="https://i.stack.imgur.com/VdyKy.png" src="https://etrip.eimg.top/images/2019/05/07/timg.gif" /></a>

Now in scan VC we got this just under the class declaration

weak var firstViewController: HiddingViewController?

Now later in your code, when your ready to return I simply set my concerned variables in my firstViewController like this ...

self.firstViewController?.globalUUID = code

Which I have setup in the HiddingViewController like this ...

var globalUUID: String? { didSet { startScanning() } }

So basically when I close the scanning VC I set the variable globalUUID which in term starts the scanning method here.


Very simple solution actually... Just put your animation in the viewDidAppear method. This method is called every time the view loads.

class firstViewController: UIViewController { override func viewDidAppear(_ animated: Bool) { super.viewDidAppear(animated) // insert animation here to run when FirstViewController appears... } }


  • Django: 400 Error with Debug=False and ALLOWED_HOSTS=[“*”]
  • Cannot read property “search” of undefined
  • DataTables - Search in multiple columns with a single drop down
  • Why Nullable can't compile but int? does without 'using System;'
  • MSVC C4100: 'application' : unreferenced formal parameter warning
  • Root priv can't be dropped in python even after seteuid. A bug?
  • Trigger sendgrid template email using meteor
  • How to filter angular model (array) without destroying it
  • Share folder from docker container to host
  • Preparing apps for the nexus 10
  • LINQ groupby statement with key
  • Adding Custom Lint Rules
  • Simulate external stroke ::before pseudo elements: problem with transparent text
  • Django get attributes from foreign key's class
  • amcharts line to be changed with different color if it goes down to the other line(after intersectin
  • NSView Contraints - How can I force the aspect ratio of a subview to stay constant?
  • How do i create an accordion control similar to one created using AJAX in IOS?
  • Memory Leak UITableView
  • Sorting list of dictionaries according to specific order
  • type “e” does not exist , Redshift through Postgresql connector in php codeigniter
  • Publish ASP.NET MVC Application : read configuration file permissions
  • Java Regex Finding digits in a String
  • Is there a way to assign DST transitions automatically in lubridate?
  • How to do handle login-logoff
  • Disabling Add to Cart Button for Specific WooCommerce Products
  • Convert certificate to byte array
  • ExecuteSQL doesn't select table if it having dateTime Offset value?
  • Prevent user account creation with sign in by email in firestore
  • Antialiasing on OpenGL ES 2.0
  • Java Processbuilder Stream to Python-Script
  • Is there a GetMouseMovePointsEx function in Lazarus?
  • How to implement 'if' in Gherkin
  • Lazy Evaluation - Space Leak
  • SCNText Not Displaying
  • Bootstrap 3 Validation
  • what is “Other” category in CosmosDB monitoring graph?
  • analytics.js event not working properly
  • Custom Data Generator for Keras LSTM with TimeSeriesGenerator
  • How to have non scrolling content in a UIScrollView
  • SpringBoot: Bypass OncePerRequestFilter filters