如何在Swift中弹出特定的视图控制器

64

我使用以下Objective-C代码弹出特定的ViewController

for (UIViewController *controller in self.navigationController.viewControllers) {
    if ([controller isKindOfClass:[AnOldViewController class]]) { 
        //Do not forget to import AnOldViewController.h
        [self.navigationController popToViewController:controller
                                              animated:YES];
        break;
    }
}
如何在Swift中实现呢?

14
用 Swift 语法完全相同的方式,你尝试了什么?在尝试过程中出现了什么问题?(例如:出现了特定的错误信息或不符合预期的运行时行为) - Duncan C
19个回答

133

请尝试以下代码:

for controller in self.navigationController!.viewControllers as Array {
    if controller.isKind(of: ViewController.self) {
        self.navigationController!.popToViewController(controller, animated: true)
        break
    }
}

2
如果我的当前视图控制器是一个模型,该怎么办? - Jayprakash Dubey
请看这个问题:https://stackoverflow.com/questions/49270459/how-to-change-class-dynamically-for-view-controller-using-interface-builder - dinesh sharma

45

Swift 5

要弹出到特定类的最新实例,例如SomeViewController

navigationController?.popToViewController(ofClass: SomeViewController.self)

但是你需要添加这个UINavigationController扩展:

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

11
目前为止最干净的Swift 5答案。 - Tuan Anh Vu
我更喜欢这样检查: viewControllers.last(where: { $0 is ofClass }) { ... }。你不需要使用isKind(of:)。这样会让代码更简洁。 - Starsky

36

适用于Swift 3及以上版本

let viewControllers: [UIViewController] = self.navigationController!.viewControllers
for aViewController in viewControllers {
    if aViewController is YourViewController {
        self.navigationController!.popToViewController(aViewController, animated: true)
    }
}

26

从 Swift 4.0 及以上版本开始

for controller in self.navigationController!.viewControllers as Array {
        if controller.isKind(of: DashboardVC.self) {
            _ =  self.navigationController!.popToViewController(controller, animated: true)
            break
        }
    }

这个运作得非常完美。


它在 Swift 5 上也完美地工作。 - Soorej Babu

18

我希望有一种通用的方法来做这件事。

我有一个针对UINavigationController的扩展:

extension UINavigationController {

   func backToViewController(vc: Any) {
      // iterate to find the type of vc
      for element in viewControllers as Array {
         if "\(element.dynamicType).Type" == "\(vc.dynamicType)" {
            self.popToViewController(element, animated: true)
            break
         }
      }
   }

}

假设我有一个名为FOHomeVC的类(它是一个UIViewController),在导航堆栈中实例化。

那么在我的代码中,我会这样写:

self.navigationController?.backToViewController(FOHomeVC.self)

self.navigationController?.backToViewController(vc: ViewController())自我.navigationController?.backToViewController(vc:ViewController()) - shubh14896

6

我为UINavigationController添加了一个扩展,帮助你查找该控制器是否存在于导航栈中。如果存在,则会弹出到该控制器,否则您可以通过pushController参数传递新的控制器进行推送。

extension UINavigationController {

    func containsViewController(ofKind kind: AnyClass) -> Bool {
        return self.viewControllers.contains(where: { $0.isKind(of: kind) })
    }

    func popPushToVC(ofKind kind: AnyClass, pushController: UIViewController) {
        if containsViewController(ofKind: kind) {
            for controller in self.viewControllers {
                if controller.isKind(of: kind) {
                    popToViewController(controller, animated: true)
                    break
                }
            }
        } else {
            pushViewController(pushController, animated: true)
        }
    }
}

6

Swift 4 / Swift 5

 for controller in self.navigationController!.viewControllers as Array {
            if controller.isKind(of: HomeViewController.self) {
                self.navigationController!.popToViewController(controller, animated: true)
                break
            }
        }

5
我更喜欢“真正的通用”和更实用的方法。
因此,我提出了以下UINavigationController扩展函数。您还可以使用第一个函数,用于任何需要访问导航栈中特定VC的情况。

扩展

extension UINavigationController {
    func getViewController<T: UIViewController>(of type: T.Type) -> UIViewController? {
        return self.viewControllers.first(where: { $0 is T })
    }

    func popToViewController<T: UIViewController>(of type: T.Type, animated: Bool) {
        guard let viewController = self.getViewController(of: type) else { return }
        self.popToViewController(viewController, animated: animated)
    }
}

使用方法

self.navigationController?.popToViewController(of: YourViewController.self, animated: true)



以下内容至少适用于Swift 4和5。


4

如果存在的话,从导航栏堆栈中找到您的视图控制器并弹出该视图控制器。

for vc in self.navigationController!.viewControllers {
    if let myViewCont = vc as? VCName 
    {
        self.navigationController?.popToViewController(myViewCont, animated: true)
    }
}

4

swift5

let controllers : Array = self.navigationController!.viewControllers
self.navigationController!.popToViewController(controllers[1], animated: true)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接