Visual artifact when dismissing more than one modal view controller at once Visual artifact when dismissing more than one modal view controller at once objective-c objective-c

Visual artifact when dismissing more than one modal view controller at once


Actually there's no way to do it by just using dismissViewControllerAnimated:completion: method no matter where you put it or how you call it (at least I couldn't, if someone knows a way - we all want to know).


HOWEVER, there's a hack you can use to achieve your desired outcome (this code should be called from "B" ViewController):

// Snapshot of "C" ViewControllerUIGraphicsBeginImageContextWithOptions([UIScreen mainScreen].bounds.size, YES, 0);UIView *snapshot = [self.presentedViewController.view snapshotViewAfterScreenUpdates:NO];UIGraphicsEndImageContext();// Cover the entire view of "B" (and hide navigation bar)[self.view addSubview:snapshot];self.navigationController.navigationBarHidden = YES;// Dismiss "C" without animation[self.presentedViewController dismissViewControllerAnimated:NO completion:^{    // Dismiss "B" with animation    [self.presentingViewController dismissViewControllerAnimated:YES completion:nil];}];


If you are using a Storyboard then this should be achievable using Unwind Segues. Mike Woelmer has a good set of articles about this. Basically you provide information to the Storyboard about how a view can unwind through several different views to get a to a view that's already on the stack.

However, I'm a bit confused in the same way that Jeffery Thomas is in the comments: why are you presenting a navigation controller with another navigation controller? I can understand that you might want the navigation bar to look different on different views, but you can customise that when the view is due to appear. You should think a bit about the content of the views in NavB and NavC and ask yourself whether they are supposed to be presented as modal views or whether they would be better off as part of a single navigation stack. By presenting each Navigation Controller modally you're ending up with multiple navigation stacks, not a single stack with multiple view controllers. Even if just NavB and NavC were part of the same stack it would probably remove the visual glitch you're seeing.

If you did use a single navigation controller then you can get back to a previous view controller in the navigation stack by using the method -popToViewController:animated: on UINavigationController.

If you decide that presenting NavB and NavC modally as you are currently doing is the right thing to do then you are likely to get into trouble because when you ask NavA to dismiss its view controller it will try to dismiss NavB, which to it means setting up a transition between the NavB's view and NavA's view. That's why you're seeing that transition, and not the one you want (which is between NavC's view and NavA's). One way which might work (and sounds a bit weird) is to try to present NavA from NavC, then override the transition to make it look like you're popping NavC off the stack. Once you're there you can clean things up by removing any strong references to NavB and NavC. This article from Ash Furrow will get you most of the way.


You can fake the animation to look exactly as you wish:

  • pop/dismiss B and C without animation
  • push/present C without animation
  • pop/dismiss C using whatever animation you wish