如何检查viewcontroller是否添加到堆栈中

时间:2017-03-16 05:33:51

标签: ios swift uiviewcontroller

我有两个视图控制器。我按下按钮使用下面的代码,从一个视图导航到另一个视图。

 *let secondViewController = self.storyboard!.instantiateViewControllerWithIdentifier("NotificationController") as! NotificationController

self.navigationController!.pushViewController(secondViewController, animated: true)*

对于背面,我使用条形按钮上的条形按钮单击以使用下面的代码。

 self.navigationController?.popViewControllerAnimated(true)

所以我的问题是如果我连续从一个视图转到另一个视图然后它添加到堆栈中。我想只显示另一个视图,当它已经添加到堆栈中以停止添加它时。它只会增加一次。

10 个答案:

答案 0 :(得分:16)

要检查导航堆栈是否包含特定类型的view controller,您可以使用:

if let viewControllers = self.navigationController?.viewControllers
{
    if viewControllers.contains(where: {
        return $0 is YourViewController
    })
    {
        //Write your code here
    }
}

要从导航堆栈中删除特定控制器,您需要更改导航堆栈。

示例:

    if var viewControllers = self.navigationController?.viewControllers
    {
        for controller in viewControllers
        {
            if controller is UIViewController
            {
                viewControllers.removeElement(controller)
                self.navigationController?.viewControllers = viewControllers
            }
        }
    }

答案 1 :(得分:10)

对于swift 4,您可以使用

 if let viewControllers = self.navigationController?.viewControllers {
       for vc in viewControllers {
            if vc.isKind(of: YourViewController.classForCoder()) {
                 print("It is in stack")
                 //Your Process
            }
       }
 }

答案 2 :(得分:5)

阐述PGDev的答案,对于Swift 4.1

如何从UIViewController堆栈中删除特定的UINavigationController子类:

/// Given 'nc' is a valid UINavigationController instance,
/// removes all instances of MyViewController from the stack

nc.viewControllers = nc.viewControllers.filter { !($0 is MyViewController) }

将它作为扩展名:

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

<强>用法:

guard let nc = self.navigationController else { return }

let exists = nc.containsViewController(ofKind: MyViewController.self)

nc.removeAnyViewControllers(ofKind: MyViewController.self)
顺便说一句,如果有人知道如何限制“善良”的话。到UIViewController的子类,请大声喊出来。

答案 3 :(得分:2)

以下是检查它的代码。

if let viewControllers = navigationController?.viewControllers {
    for viewController in viewControllers {
        // some process
        if viewController.isKindOfClass(ViewControllerClassName) {
            println("yes it is")
        }
    } 
}

答案 4 :(得分:1)

您可以查看以下code

目标 - 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")
                }
            } 
        }

答案 5 :(得分:1)

我们走了。

这一行将为您提供一个UIViewControllers数组

self.navigationController?.viewControllers

现在你需要做的是检查你的viewControllerObject是否存在?

写这行

if viewController.isKindOfClass(YourController){
}

这是一个完整的代码。

if let viewControllers = self.navigationController?.viewControllers {
            for viewController in viewControllers {

                if viewController.isKindOfClass(YourController) {
                    print("Your controller exist")
                }
       } 
}

当您回到“ViewControllerA”时写下面的行,它将从导航堆栈中删除ViewControllerB。

self.navigationController?.popViewControllerAnimated(true)

这与我们正在使用堆栈进行类似的pop操作,而navigationcontroller是一个堆栈。

如果您有任何疑惑,请告诉我。

答案 6 :(得分:0)

extension UINavigationController {
    public func hasViewController(ofKind kind: AnyClass) -> UIViewController? {
        return self.viewControllers.first(where: {$0.isKind(of: kind)})
    }
}

使用

self.navigationController.hasViewController(ofKind: #ViewControllerName#.self)

答案 7 :(得分:0)

Swift 5(工作正常)。 检查视图控制器是否堆叠在导航中的更好方法是仅要求视图控制器的可访问性。 下面。我使用此代码段返回到以前的视图控制器。

    if self.navigationController?.accessibilityActivate() != nil {
        self.navigationController?.popViewController(animated: true)
    } else {
        self.dismiss(animated: true, completion: nil)
    }

答案 8 :(得分:0)

这是另一种方法:

    guard let controllersInStack = navigationController?.viewControllers else { return }
    if let yourViewController = controllersInStack.first(where: { $0 is YourViewController }) {
        // Do what you want with yourViewController
    }

答案 9 :(得分:0)

您需要做的只是检查viewController的 nibName ,您就会得到结果

下面的这段代码将确保您不会在navigatoinController中再次添加一个viewController,

    var VC = YourViewController
    var objVC = (storyboard.instantiateViewController(withIdentifier: "YourViewController"))
    
if navigationController.viewControllers.contains(where: { (VC) -> Bool in
            return objVC.nibName == VC.nibName
        }){
            for (i,controller) in navigationController.viewControllers.enumerated()
            {
                if controller.isKind(of: VC){
                    navigationController.viewControllers.remove(at: i)
                    navigationController.pushViewController(objVC, animated: false)
                }
            }
        }else{navigationController.pushViewController(objVC, animated: false)}

,如果您只想检查viewController是否在NaviagtionController中,请尝试以下操作:

var checkForView = navigationController.viewControllers.contains(where: { (VC) -> Bool in
            return objVC.nibName == VC.nibName
        })