如何从导航控制器一次弹出两个视图?

时间:2011-11-23 03:23:22

标签: iphone ios uinavigationcontroller pop

我想弹出导航堆栈上的第三个视图回到第一个视图。

我知道如何一次弹出一个视图:

[self.navigationController popViewControllerAnimated:YES];

但我怎么一次做两个呢?

...谢谢

19 个答案:

答案 0 :(得分:126)

您可以尝试在导航控制器堆栈之间跳转

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

答案 1 :(得分:53)

以下是两个可以解决您问题的UINavigationController扩展程序。我建议使用弹出到特定类UIViewController的第一个:

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)
    }
  }

}

并像这样使用它:

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

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

答案 2 :(得分:43)

您可以使用popToRootViewControllerAnimated

弹出“root”(第一个)视图控制器
[self.navigationController popToRootViewControllerAnimated:YES];

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

UINavigationController Reference

  

弹出除根视图控制器之外的堆栈上的所有视图控制器并更新显示。

     

返回值
  从堆栈中弹出的一组视图控制器。

答案 3 :(得分:29)

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

objectAtIndex:1 - >你可以传递你想要弹出的索引

答案 4 :(得分:18)

Swift 2 - xCode 7.3

这可能是弹出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")
        }
    }
}

答案 5 :(得分:15)

如果你只是想一次弹出2因为你的rootViewController(更深)'然后2你可以考虑在UIviewController中添加一个类别,例如:

的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 "UINavigationController+popTwice.h",并使用此行代码一次弹出2个控制器:

[self.navigationController popTwoViewControllersAnimated:YES];

不是很好吗? :)

答案 6 :(得分:6)

//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];

答案 7 :(得分:5)

你也可以尝试这个: -

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

答案 8 :(得分:4)

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

答案 9 :(得分:4)

在Swift 3中, 您可以从导航控制器中弹出一个,两个或更多个视图控制器,如

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

这里FromWhereYouWantToGoController是目标控制器。希望能帮助到你。

答案 10 :(得分:3)

您可以传递初始视图控制器(您想要返回的控制器),然后在最后一个视图中调用此行:

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

L,

答案 11 :(得分:3)

  

快捷键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)
    }
}

然后使用此方法

self.popViewControllerss(popViews: 2)

答案 12 :(得分:3)

我在这里没有看到这个答案。如果你只想弹出一些(不是一直到root),你可以通过self.navigationController.viewControllers迭代检查类类型,或者你有一个引用使用:

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

答案 13 :(得分:2)

您可以弹回根视图控制器

[self.navigationController popToRootViewControllerAnimated:YES];

或者,如果要弹出的视图不是第一个,则需要在上一个视图中再次弹出viewWillAppear

答案 14 :(得分:2)

这是我用来返回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];
    }
}

答案 15 :(得分:1)

您可以使用UIViewControllers的堆栈。  1.获取堆栈中所有viewControllers的数组。  2.遍历整个数组并找到所需的viewController
    通过匹配类类型。  3.弹出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)
            }
        }
}

答案 16 :(得分:1)

Swift版本(Swift 1.2 / Xcode 6.3.1) 弹出两次或更多次

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

 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)

答案 17 :(得分:0)

使用简单的 UINavigationController扩展

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

答案 18 :(得分:-1)

Swift 4.2

在您的navigationController?.viewControllers上,您可以在导航控制器上检查viewControllers,因此您只需要弹出想要的位置即可,

navigationController?.popToViewController(navigationController?.viewControllers[1], animated: true)

我要弹出的ViewController的位置是1。