Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 375
Martin.Zeng Avatar asked Oct 22 '17 08:10

Martin.Zeng


2 Answers

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()
         }
 }
like image 133
Usman Avatar answered Sep 28 '22 19:09

Usman


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?()
         }
        */
    }

}
like image 20
DenZhukov Avatar answered Sep 28 '22 18:09

DenZhukov