How to Dismiss 2 Modal View Controllers in Succession?

24,465

Solution 1

Try using the next code in B (right after dismissing C, as you already do):

[self.parentViewController dismissModalViewControllerAnimated:YES];

IMPORTANT:
Don't do anything in the method after this line.
This view controller (B) probably will be released and deallocated...

UPDATE:
Starting from iOS7 the method above is deprecated.
Use the next method instead:

[self.parentViewController dismissViewControllerAnimated:YES completion:^{ /* do something when the animation is completed */ }];

Solution 2

Just found out you need to use presentingViewController in iOS 5.

[self.presentingViewController.presentingViewController dismissModalViewControllerAnimated:YES];

A -> B -> C

Running the above code in modal C will take you back to A

Solution 3

This worked for me, very simple

// Call inside View controller C    
self.presentingViewController?.dismissViewControllerAnimated(false, completion: nil)
self.presentingViewController?.dismissViewControllerAnimated(true, completion: nil)

Explanation:

If you call dismiss on C, it can only remove C. If you call dismiss on B, it will do the right thing: Remove the topmost modal view controller. The first call therefore removes C (with no animation). The second call removes B.

The easiest way to access view controller B from C is to use the presentingViewController variable.

Solution 4

In B. Put:

[self dismissModalViewControllerAnimated:NO];
[self dismissModalViewControllerAnimated:YES];

Only run one animation.

Solution 5

In swift 4

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

Share:
24,465

Related videos on Youtube

Sheehan Alam
Author by

Sheehan Alam

iOS, Android and Mac Developer. i can divide by zero.

Updated on July 02, 2020

Comments

  • Sheehan Alam
    Sheehan Alam almost 4 years

    I have 2 view controllers presented modally.

    A presents B which presents C.
    

    When I dismiss C I would like to dismiss B as well. But I am not sure how to do this:

    Dismiss C:

    [self dismissModalViewControllerAnimated:YES]
    //[delegate dismissB] //this doesn't work either when i create a delegate pattern
    

    Now I am left with B. How can I dismiss B from C?

  • Sheehan Alam
    Sheehan Alam almost 14 years
    I tried this but it just simply dismisses C. B is still visible.
  • Michael Kessler
    Michael Kessler almost 14 years
    Try dismissing C without animation and then dismiss B with animation... BTW, where is this dismissing code located (which class and how is this method called)?
  • Sheehan Alam
    Sheehan Alam almost 14 years
    Dismissing code is located in C in a method called dismissAll. It is triggered by pressing a UIBarButtonItem.
  • Michael Kessler
    Michael Kessler almost 14 years
    I was sure that it is located in B when I wrote my answer... The common solution for dismissing modal view controllers is to call a method in delegate (view controller that opened the modal one) and in that method the modal view controller should be dismissed. In your case A should be a delegate of B and B should be a delegate of C; in C you should call a delegate method in B that should dismiss C and call a delegate method in A, that should dismiss B... I hope it is clear enough now.
  • kris
    kris over 12 years
    this approach seems to be working very nicely. Anyone out there see any downsides to this approach?
  • Andy Davies
    Andy Davies about 12 years
    No problem :-) Every example I came across was for pre iOS5 and never worked
  • JastinBall
    JastinBall almost 10 years
    It would be correct to dismiss view controller from presentingViewController using delegate. (According to Apple guides)
  • DevC
    DevC almost 10 years
    ...dismissModalViewControllerAnimated is deprecated now. Try [self.presentingViewController.presentingViewController dismissViewControllerAnimated:YES completion:nil];
  • fatuhoku
    fatuhoku about 9 years
    This method is deprecated in iOS 7/8 — what should take its place?
  • Ted
    Ted over 8 years
    this works on ios7, but in ios8 if B is presented with modalPresentationStyle OverCurrentContextyou have to call the [A dismissController] twice
  • Ramis
    Ramis almost 7 years
    More generic way to dismiss more that one modal view controllers is here
  • Nikunj Joshi
    Nikunj Joshi over 6 years
    Messaging arguments in Objective-C is not separated by coma, so It will be without coma after "true" for // Objective-C [self.presentingViewController dismissViewControllerAnimated: true completion: nil]
  • Mihir Oza
    Mihir Oza over 6 years
    B is not dismissed when I add your code and please update your objective c syntax also. remove the comma after true.
  • Hedylove
    Hedylove almost 5 years
    Wasn't working for me because I had it in the completion block of controller C's dismiss method... realized of course it wouldn't work, self is nil! lol
  • clopex
    clopex almost 3 years
    For Swift 5, I use this and it works: self.presentingViewController?.dismiss(animated: false) self.presentingViewController?.dismiss(animated: true)