How do I pop two views at once from a navigation controller?

IosIphoneUinavigationcontroller

Ios Problem Overview


I want to pop to the third view on the navigation stack back to the first view.

I know how to pop one view at once:

[self.navigationController popViewControllerAnimated:YES];

But how do I do two at once?

Ios Solutions


Solution 1 - Ios

You can try this to Jump between the navigation controller stack as well

NSMutableArray *allViewControllers = [NSMutableArray arrayWithArray:[self.navigationController viewControllers]];
for (UIViewController *aViewController in allViewControllers) {
    if ([aViewController isKindOfClass:[RequiredViewController class]]) {
        [self.navigationController popToViewController:aViewController animated:NO];
    }
}

Solution 2 - Ios

Here are two UINavigationController extensions that can solve your problem. I would recommend using the first one that pops to a UIViewController of a specific class:

extension UINavigationController {

  func popToViewController(ofClass: AnyClass, animated: Bool = true) {
    if let vc = viewControllers.filter({$0.isKind(of: ofClass)}).last {
      popToViewController(vc, animated: animated)
    }
  }

  func popViewControllers(viewsToPop: Int, animated: Bool = true) {
    if viewControllers.count > viewsToPop {
      let vc = viewControllers[viewControllers.count - viewsToPop - 1]
      popToViewController(vc, animated: animated)
    }
  }

}

and use it like this:

// pop to SomeViewController class
navigationController?.popToViewController(ofClass: SomeViewController.self)

// pop 2 view controllers
navigationController?.popViewControllers(viewsToPop: 2)

Solution 3 - Ios

You can pop to the "root" (first) view controller with popToRootViewControllerAnimated:

[self.navigationController popToRootViewControllerAnimated:YES];

// If you want to know what view controllers were popd:
// NSArray *popdViewControllers = [self.navigationController popToRootViewControllerAnimated:YES];

UINavigationController Reference:

> Pops all the view controllers on the stack except the root view controller and updates the display. > > Return Value
> An array of view controllers that are popped from the stack.

Solution 4 - Ios

[self.navigationController popToViewController:[self.navigationController.viewControllers objectAtIndex:1] animated:YES];	

objectAtIndex:1 --> you can pass whichever index you want to pop to

Solution 5 - Ios

Swift 2 - xCode 7.3

This could be a very useful extension to pop UIViewControllers:

extension UINavigationController {

    func popToViewControllerOfType(classForCoder: AnyClass) {
        for controller in viewControllers {
            if controller.classForCoder == classForCoder {
                popToViewController(controller, animated: true)
                break
            }
        }
    }

    func popViewControllers(controllersToPop: Int, animated: Bool) {
        if viewControllers.count > controllersToPop {
            popToViewController(viewControllers[viewControllers.count - (controllersToPop + 1)], animated: animated)
        } else {
            print("Trying to pop \(controllersToPop) view controllers but navigation controller contains only \(viewControllers.count) controllers in stack")
        }
    }
}

Solution 6 - Ios

If you just want to pop 2 at once because your rootViewController is (way) 'deeper' then 2 you could consider adding a category to UIviewController for example:

UINavigationController+popTwice.h
#import <UIKit/UIKit.h>
@interface UINavigationController (popTwice)

- (void) popTwoViewControllersAnimated:(BOOL)animated;

@end
UINavigationController+popTwice.m
#import "UINavigationController+popTwice.h"

@implementation UINavigationController (popTwice)

- (void) popTwoViewControllersAnimated:(BOOL)animated{
    [self popViewControllerAnimated:NO];
    [self popViewControllerAnimated:animated];
}

@end

Import the category #import "UINavigationController+popTwice.h" somewhere in your implementation and use this line of code to pop 2 controllers at once:

[self.navigationController popTwoViewControllersAnimated:YES];

isn't that great? :)

Solution 7 - Ios

> Swift 4 :

func popViewControllerss(popViews: Int, animated: Bool = true) {
    if self.navigationController!.viewControllers.count > popViews
    {
        let vc = self.navigationController!.viewControllers[self.navigationController!.viewControllers.count - popViews - 1]
         self.navigationController?.popToViewController(vc, animated: animated)
    }
}

Then Use This Method

self.popViewControllerss(popViews: 2)

Solution 8 - Ios

You can also try this one :-

[self.navigationController popToViewController:yourViewController animated:YES];

Solution 9 - Ios

//viewIndex = 1;
//viewIndex = 2;
//viewIndex = 3;

// **[viewControllers objectAtIndex: *put here your viewindex number*]

NSArray *viewControllers = [self.navigationController viewControllers];
[self.navigationController popToViewController:[viewControllers objectAtIndex:viewIndex] animated:NO];

Solution 10 - Ios

    NSMutableArray *newStack = [NSMutableArray arrayWithArray:[self.navigationController viewControllers]];
    [newStack removeLastObject];
    [newStack removeLastObject];
    [self.navigationController setViewControllers:newStack animated:YES];

Solution 11 - Ios

In Swift 3, you can pop one, two or more viewcontrollers from navigation controller like that

let viewControllers = self.navigationController!.viewControllers as [UIViewController]
    for aViewController:UIViewController in viewControllers {
        if aViewController.isKind(of: FromWhereYouWantToGoController.self) {
            _ = self.navigationController?.popToViewController(aViewController, animated: true)
        }
    }

Here FromWhereYouWantToGoController is destination controller. Hope it helps.

Solution 12 - Ios

You can pass the initial view controller (the one you want to come back to) and then call this line in the last view:

[self.navigationController popToViewController:yourInitialViewController animated:YES];

L.

Solution 13 - Ios

I didn't see this answer in here. If you only want to pop a few (not all the way to the root), you can just iterate through self.navigationController.viewControllers checking for class types, or if you have a reference use that:

for (UIViewController *aViewController in self.navigationController.viewControllers) {
   if ([aViewController isKindOfClass:[SMThumbnailViewController class]]) {
      [self.navigationController popToViewController:aViewController animated:YES];
   }
}

Solution 14 - Ios

you can pop back to the root view controller

[self.navigationController popToRootViewControllerAnimated:YES];

or, if the view you want to pop to isn't the first one, you'll need to pop again in your previous view's viewWillAppear

Solution 15 - Ios

Here's a little function I'm using to go back X ViewControllers:

-(void)backMultiple:(id)data {
	int back = 2; //Default to go back 2 
	int count = [self.navigationController.viewControllers count];

	if(data[@"count"]) back = [data[@"count"] intValue];
	
	//If we want to go back more than those that actually exist, just go to the root
	if(back+1 > count) {
		[self.navigationController popToRootViewControllerAnimated:YES];
	}
	//Otherwise go back X ViewControllers 
	else {
		[self.navigationController popToViewController:[self.navigationController.viewControllers objectAtIndex:count-(back+1)] animated:YES];
	}
}

Solution 16 - Ios

Swift Version as of (Swift 1.2 / Xcode 6.3.1) of popping twice or more

 var viewControllers = self.navigationController?.viewControllers
 viewControllers?.removeLast()
 viewControllers?.removeLast()
 self.navigationController?.setViewControllers(viewControllers, animated: true)

or

 var viewControllers = self.navigationController?.viewControllers
 var viewsToPop = 2
 var end = (viewControllers?.count)!
 var start = end - viewsToPop
 viewControllers?.removeRange(Range<Int>(start: start, end: end))
 self.navigationController?.setViewControllers(viewControllers, animated: true)

Solution 17 - Ios

**You can use the stack of the UIViewControllers.

  1. Fetch the array of all the viewControllers in the stack.

  2. Iterate through the whole array and find the desired viewController
    by matching the class type.

  3. Pop the viewController.**

    func popToSpecificViewC { let viewControllers: [UIViewController] = self.navigationController!.viewControllers as [UIViewController]; for viewController:UIViewController in viewControllers { if viewController.isKind(of: WelcomeViewC.self) { _ = self.navigationController?.popToViewController(viewController, animated: true) } } }

Solution 18 - Ios

Using a simple UINavigationController extension:

extension UINavigationController {
    func popViewControllers(_ count: Int) {
        guard viewControllers.count > count else { return }
        popToViewController(viewControllers[viewControllers.count - count - 1], animated: true)
    }
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionAdam WaiteView Question on Stackoverflow
Solution 1 - IosMeetView Answer on Stackoverflow
Solution 2 - IosbudiDinoView Answer on Stackoverflow
Solution 3 - IoschownView Answer on Stackoverflow
Solution 4 - IosZarakiView Answer on Stackoverflow
Solution 5 - IoslubilisView Answer on Stackoverflow
Solution 6 - IosTiemeView Answer on Stackoverflow
Solution 7 - IosSaifan NadafView Answer on Stackoverflow
Solution 8 - IosLeenaView Answer on Stackoverflow
Solution 9 - IosSabareeshView Answer on Stackoverflow
Solution 10 - Iospatrick-fitzgeraldView Answer on Stackoverflow
Solution 11 - IosRiajur RahmanView Answer on Stackoverflow
Solution 12 - IosLucasView Answer on Stackoverflow
Solution 13 - IosVaporwareWolfView Answer on Stackoverflow
Solution 14 - IosRobotnikView Answer on Stackoverflow
Solution 15 - IosMarkView Answer on Stackoverflow
Solution 16 - IosGlenn SView Answer on Stackoverflow
Solution 17 - IosPeeyush karnwalView Answer on Stackoverflow
Solution 18 - IosBalázs VinczeView Answer on Stackoverflow