Dismiss Modal UIViewController during handoff

296 views Asked by At

I'm trying to add handoff to my App. When my App is waken by Handoff I need to dismiss several ViewControllers to return to a MKMapView located in my view hierarchy.

My view hierarchy looks like:

+NavController

+--- MyMapViewController (contains the MKMapView where I want to go, top of the NavController)

+--- MyTabbarViewController (it's a tab bar with several views...)

+--- MyOverviewViewController (pushed on the stack of my NacController by a VC that displayed in MyTabbarViewController)

 +--- MyDetailViewController (it's a modal view presented by MyOverviewController)

 +--- MyChartViewController (it's a modal view presented by MyDetailViewController)

When the App receives the UserActivity the displayed view controller is "MyChartViewController".

To show the result of the User Activity I need to go to the MyMapViewController to display some information on the MapView.

My issue is to find a simple way to dismiss "MyChartViewController" and "MyDetailsViewController" before to call [navController popToRootViewControllerAnimated:TRUE];

I tried [navController.visibleViewController dismissViewControllerAnimated:FALSE completion:Nil]; but it dismisses only the MyChartViewController, why?

navController.visibleViewController is the MyDetailViewController.

The only solution I found is to call: [MyChartViewController dismissViewControllerAnimated:FALSE completion:Nil]; AND [navController.visibleViewController dismissViewControllerAnimated:FALSE completion:Nil];

My view hierarchy can be more complex or different depending on where the user is located in the App when the UserActivity is triggered. I'm expecting to find a simple solution that could be used for any situation. The main issue is to dismiss the stack of modals viewController.

I always want to go back to this MyMapViewController that is on the top of the NavController.

Any idea?

Thanks!

3

There are 3 answers

0
sebastien On BEST ANSWER

Please see below my simple solution. I have written a method that dismiss all ViewControllers displayed on the top of the visible view controller of my NavigationController.

When all "modal" viewControllers are dismissed I just pop the NavigationController to the root.

It seems it's working for all situations I have to manage in my App.

+(void) dismissModalAndPopToRoot:(UINavigationController*) navController {

if (navController.visibleViewController.parentViewController == Nil) {
    // it's not a children of the NavController, so it's most probably a modal or several modals
    UIViewController* currentViewController = navController.visibleViewController;
    NSMutableArray* stackOfPresentedVC = [[NSMutableArray alloc] init];

    while (currentViewController.presentedViewController != Nil) {
        [stackOfPresentedVC addObject:currentViewController];
        currentViewController = currentViewController.presentedViewController;
    }
    [stackOfPresentedVC addObject:currentViewController];

    for (NSInteger i = (stackOfPresentedVC.count) - 1; i >= 0; i--) {
        currentViewController = stackOfPresentedVC[i];
        [currentViewController dismissViewControllerAnimated:FALSE completion:Nil];
    }
}

[navController popToRootViewControllerAnimated:TRUE];

}

0
Adam Jenkins On

If the root view controller is always the MyMapViewController, then this task is kind of easy - just set the root view controller of the window again to be a UINavigationController that has the MyMapViewController as root.

0
DanR On

I would set up and unwindSegue in the VC you want to unwind to, and then in the VC you want to dismiss I would check the conditions for the unWind in viewWillAppear: and call the unwind if it meets the conditions