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

Ios 如何在Swift中弹出特定的视图控制器,ios,swift,uiviewcontroller,Ios,Swift,Uiviewcontroller,我使用下面的Objective-C代码弹出一个特定的ViewController for (UIViewController *controller in self.navigationController.viewControllers) { if ([controller isKindOfClass:[AnOldViewController class]]) { //Do not forget to import AnOldViewController.h

我使用下面的
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中执行此操作?

请尝试以下代码:

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

适用于Swift 3+

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

我更喜欢一种通用的方法

我有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)

请在Swift 3.0中使用以下代码:

 let viewControllers: [UIViewController] = self.navigationController!.viewControllers as [UIViewController];

for aViewController:UIViewController in viewControllers {
            if aViewController.isKind(of: YourViewController.self) {
                _ = self.navigationController?.popToViewController(aViewController, animated: true)
            }
        }

Swift 4.0

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

这是完美的工作方式。

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

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)
        }
    }
}
最新的swift

   @IBAction func popToConversationsVC(_ sender: UIButton) {
        if (self.navigationController != nil) {
            for vc in  self.navigationController!.viewControllers {
                if vc is ConversationsVC {
                     self.navigationController?.popToViewController(vc, animated: false)
                }
            }
            }
    }

从导航堆栈中找到视图控制器,并弹出到该视图控制器(如果存在)

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

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
            }
        }
let controllers : Array = self.navigationController!.viewControllers
self.navigationController!.popToViewController(controllers[1], animated: true)

我需要使用它,因为在某些情况下应用程序崩溃:

if let navVC = self.navigationController {
                    let views = navVC.viewControllers as Array
                    for controller in views {
                        if controller.isKind(of: YourVC.self) {
                            navVC.popToViewController(controller, animated: true)
                            return
                        }
                    }
                }

Swift 5

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

navigationController?.popToViewController(ofClass: SomeViewController.self)
但您需要添加以下扩展名:

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

没有力展开的简单最佳解决方案是

if let vc = navigationController.viewControllers.filter({$0 is YourViewController}).first as? YourViewController {
            self.navigationController.popToViewController(vc, animated: true)
            }

swift5

 for controller in self.navigationController!.viewControllers as Array {
            if controller.isKind(of: HomeViewController.self) {
                self.navigationController!.popToViewController(controller, animated: true)
                break
            }
        }
let controllers : Array = self.navigationController!.viewControllers
self.navigationController!.popToViewController(controllers[1], animated: true)
我更喜欢“真正的通用”和更实用的方法

因此,我提出了以下
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)
    }
}



这至少在Swift 4和Swift 5中有效。

Swift 5@PabloR的答案如下:

extension UINavigationController {

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

}
用法:

self.navigationController?.backToViewController(vc: TaskListViewController.self)

对于Swift 4.0及以上版本,使用过滤器

guard let VC = self.navigationController?.viewControllers.filter({$0.isKind(of: YourViewController.self)}).first else {return}
self.navigationController?.popToViewController(VC, animated: true)

完全一样,但语法很快。你试过什么,试的时候出了什么问题?(您不希望看到的特定错误消息或运行时行为)。如果我的当前视图控制器是一个模型,该怎么办?看这个问题:-self.navigationController?.backToViewController(vc:ViewController())是迄今为止swift 5最清晰的答案