33

I am presenting a view controller from a view controller called HomeController like so:

let viewController = self.storyboard?.instantiateViewController(withIdentifier: "LoginController") as! LoginController

let navigationController: UINavigationController = UINavigationController(rootViewController: viewController)

present(navigationController, animated: true, completion: nil)

In the presented view controller LoginController at some point gets dismissed:

self.dismiss(animated: true, completion: nil)

But when it comes back to HomeController it is not calling viewWillAppear, I really need to check on condition on HomeController when it comes back to it, So how can I call viewWillAppear when LoginController dismisses the view?

mfaani
  • 28,843
  • 15
  • 145
  • 252
user979331
  • 9,373
  • 64
  • 206
  • 383

4 Answers4

41

You need to set the correct presentationStyle. If you want that your presentedController will be fullScreen and call it the previous viewWillAppear, then you can use ".fullScreen"

let viewController = self.storyboard?.instantiateViewController(withIdentifier: "LoginController") as! LoginController

let navigationController: UINavigationController = UINavigationController(rootViewController: viewController)

navigationController.modalPresentationStyle = .fullScreen

present(navigationController, animated: true, completion: nil)
Kevinosaurio
  • 1,882
  • 2
  • 14
  • 18
  • 1
    I tried this viewWillAppear is not being called when dimissing LoginController – user979331 Jun 28 '18 at 18:44
  • 1
    @user979331 sorry my Bad is *.fullScreen* – Kevinosaurio Jun 28 '18 at 18:46
  • 2
    You can click on the segue in the storyboard and under the Attributes Inspector, change the Presentation to Full Screen. For me, it is easier than writing the code. – K. Law Mar 11 '19 at 14:08
  • 1
    I know this is an old question but still relevant to keep it fresh. I had a issue with not ALL my segues being fullscreen modal presentation. It was driving me crazy but it makes sense. All view controllers presented modally must be full screen otherwise view will appear will not be called at all. Even if you miss one, the last view when dismissed to root, will not call view will appear. – Julian Silvestri Apr 06 '20 at 20:13
  • Is there any way to call willAppear after dismiss viewController if use "PresentationStyle = .overCurrentContext" ? Because I need transparent model view so can not use modalPresentationStyle = .fullScreen. – Dipak Apr 22 '21 at 07:07
  • @Dipak you can use PresentationStyle = .currentContext – Kevinosaurio Apr 23 '21 at 01:28
  • @Kevinosaurio after using PresentationStyle = .currentContex, viewWillAppear get called but lost transparency. Transparency is my basic requirement so can not use currentContex – Dipak Apr 27 '21 at 10:06
  • I works. Setting by code helped me to check the solution, also you can change it from IB in the Navigation Controller > Attributes Inspector. – tontonCD Aug 11 '21 at 14:29
5

Changing presentation style to .fullScreen works but changes the appearance of the presented view Controller. If u want to avoid that u can override the viewWillDisappear method in the presented viewcontroller and inside it add presentingViewController?.viewWillAppear(true).

Example:

 class ViewControllerA: UIViewController {
 
      override func viewDidLoad() {
          super.viewDidLoad()
          
          //put the presenting action wherever you want

          let vc = ViewControllerB()
          navigationController.present(vc, animated: true)
      }

      override func viewWillAppear(_ animated: Bool) {
           super.viewWillAppear(animated) 
           //refresh Whatever 
      }
 }

 class ViewControllerB: UIViewController {
 
      override func viewDidLoad() {
          super.viewDidLoad()
      }

      override func viewWillDisappear(_ animated: Bool) {
          super.viewWillDisappear(animated)

          //this will call the viewWillAppear method from ViewControllerA  

          presentingViewController?.viewWillAppear(true)
      }
 }
4

In iOS 13 , if you are presenting a view controller and when you are coming back viewWillAppear doesn't get called . I have changed it from present to push view controller and methods are getting called now .

Sateesh Pasala
  • 644
  • 8
  • 14
3

If presented viewController is half screen then you will have to Call the viewWillAppear of presenting viewController manually in side presented view controller's viewWillDisappear. Add following code to your Presented view controller.

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    presentingViewController?.viewWillDisappear(true)
}    

override func viewWillDisappear(_ animated: Bool) {
    super.viewWillDisappear(animated)
    presentingViewController?.viewWillAppear(true)
}

Note: you must have to call 'presentingViewController?.viewWillDisappear(true)' to get your Presenting view controllers viewWillAppear execute everytime.

VIkas
  • 31
  • 1