3

I am trying to dismiss VC b from VC c where VC c is a popover and has a button for sign out but it is not working. The structure of the flow is

VC a ----presents modally----> VC b ----presents a popover----> VC c

When the button in the popover is clicked the VC c and VC b must be dismissed so that (VC a)ViewWillAppear is called.

Dharma
  • 3,007
  • 3
  • 23
  • 38

6 Answers6

4

Try this:

You can dismiss your presentingViewController from child view controller as follow

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

When you add a ViewController as childViewController

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

If this view controller is a child of a containing view controller (e.g. a navigation controller or tab bar controller,)

weak open var parent: UIViewController? { get }

The view controller that was presented by this view controller or its nearest ancestor.

open var presentedViewController: UIViewController? { get }

The view controller that presented this view controller (or its farthest ancestor.)

open var presentingViewController: UIViewController? { get }
Harshal Valanda
  • 5,331
  • 26
  • 63
0

If ViewControllers have hierarchy like

VC a ----presents as self.present(objects, animated: true, completion: nil) modally----> VC b ---- presents as self.present(objects, animated: true, completion: nil) popover----> VC c

And there are a button on VC c to move back to VC a then you can use:

self.presentingViewController?.presentingViewController?.dismiss(animated: true, completion: nil)
Nikhlesh Bagdiya
  • 4,316
  • 1
  • 19
  • 29
0

First of all try to dismiss VC b from itself, not presenting the VC c just to check if it works, using: self.dismiss(animated: true, completion: nil) or if VC b is embedded in a navigation controller, like this: self.navigationController?.dismiss(animated: true, completion: nil)

If the one from above works, I would suggest you implement the delegation protocol, where VC c will delegate to VC b the dismissal, whenever it should be done. You could also use a completion block for that, containing the dismiss code.

Oleg Danu
  • 4,149
  • 4
  • 29
  • 47
  • but VC c does not cover the current context it is actually a popover so if user doesn't click on the popover but some where else the popover that is VC c will disappear but there would be no VC b beneath it to be displayed that would be contradictory with the flow – bakhtiar masood Jul 14 '17 at 10:45
0

Hope this works

// Call inside View controller C    
        self.presentingViewController?.dismissViewControllerAnimated(false, completion: nil)
        self.presentingViewController?.dismissViewControllerAnimated(true, completion: nil)
Vignesh Davins
  • 285
  • 1
  • 13
0
`protocol ModalHandler {
    func modalDismissed()
Class SecondViewController: UIViewController, ModalHandler {
    func modalDismissed() {
        self.dismiss(animated: false, completion: nil)
   }
   func open3rdController() {
       let thirdVC = ThirdViewController(_ )
       thirdVC.delegate = self
       self.present(thirdVC, animated: true, completion: nil)
   }
class ThirdViewController: UIViewController {
    func dismiss() {
        self.delegate.modalDismissed()
   }
}
`
0

Whats about a Presenter or a Coordinator.

This instance will initialize all these VCs and also present them. From there you can also dismiss them.

Ugo Arangino
  • 2,802
  • 1
  • 18
  • 19