I have two view controllers. I have navigated from one view to another view by press the button to using below code.
*let secondViewController = self.storyb
Elaborating on PGDev's answer, for Swift 4.1
How to remove a specific UIViewController
subclass from the UINavigationController
stack:
/// Given 'nc' is a valid UINavigationController instance,
/// removes all instances of MyViewController from the stack
nc.viewControllers = nc.viewControllers.filter { !($0 is MyViewController) }
Putting it an an extension:
extension UINavigationController
{
/// Given the kind of a (UIViewController subclass),
/// removes any matching instances from self's
/// viewControllers array.
func removeAnyViewControllers(ofKind kind: AnyClass)
{
self.viewControllers = self.viewControllers.filter { !$0.isKind(of: kind)}
}
/// Given the kind of a (UIViewController subclass),
/// returns true if self's viewControllers array contains at
/// least one matching instance.
func containsViewController(ofKind kind: AnyClass) -> Bool
{
return self.viewControllers.contains(where: { $0.isKind(of: kind) })
}
}
Usage:
guard let nc = self.navigationController else { return }
let exists = nc.containsViewController(ofKind: MyViewController.self)
nc.removeAnyViewControllers(ofKind: MyViewController.self)
BTW, if anyone knows how to constrain 'kind' to subclasses of UIViewController, please yell out.
For swift 4 you can use
if let viewControllers = self.navigationController?.viewControllers {
for vc in viewControllers {
if vc.isKind(of: YourViewController.classForCoder()) {
print("It is in stack")
//Your Process
}
}
}
Swift 5(Working tested). Better way to check whether the view controller is stacked in navigation or not is by simply asking for the view controller's accessibility.See example below.I use this snippet to go back to previous view controller.
if self.navigationController?.accessibilityActivate() != nil {
self.navigationController?.popViewController(animated: true)
} else {
self.dismiss(animated: true, completion: nil)
}
Here is the code to check it.
if let viewControllers = navigationController?.viewControllers {
for viewController in viewControllers {
// some process
if viewController.isKindOfClass(ViewControllerClassName) {
println("yes it is")
}
}
}
You can check with below code
Objective - C
NSArray * controllers = [self.navigationController viewControllers];
for (int i = 0; i < [controllers count]; i++){
UIViewController * controllerTest = [controllers objectAtIndex:i];
if([controllerTest isKindOfClass:[YourController class]]){
NSLog(@"Class is available");
}
}
Swift 3.0
if let viewControllers = self.navigationController?.viewControllers {
for viewController in viewControllers {
// some process
if viewController.isKindOfClass(YourController) {
print("Class is available")
}
}
}
extension UINavigationController {
public func hasViewController(ofKind kind: AnyClass) -> UIViewController? {
return self.viewControllers.first(where: {$0.isKind(of: kind)})
}
}
USE
self.navigationController.hasViewController(ofKind: #ViewControllerName#.self)