检测您是否要转到新的视图控制器或之前

时间:2017-06-21 07:32:49

标签: ios swift uinavigationcontroller

我有一个导航视图控制器,想象一下这种情况:

我的观点控制器: vc1,vc2,vc3,vc4

我的根导航控制器: nc

视图控制器的堆栈是这样的:

nc> vc1> vc2> VC3

现在我在vc3。我想知道如果你要去以前的视图控制器(vc2),或者你正在转向新的(v4)。

猜猜这应该在viewWillDisappear方法上检查。

我试着用它来检查:

self.isMovingFromParentViewController()

但如果前一个vc是导航根,它只会返回true。

您需要的任何进一步信息,请告诉我,谢谢。

修改

self.navigationController?.pushViewController(imageViewController, animated: true)

转到上一个视图控制器:

我没有使用解雇,只是翻转或推回导航按钮。

(Swift 2.3)

3 个答案:

答案 0 :(得分:1)

我已经在Objective-C中找到了这个解决方案(same question),但是我把它翻译成了Swift,我又进行了一次修改。因为我没有解除视图控制器,所以如果你没有推动视图控制器那么你就会回来。

    if let viewControllers = self.navigationController?.viewControllers {
        if viewControllers.count > 1 && viewControllers[viewControllers.count-2] == self {
            print("New view controller was pushed")
        }
        else {
            print("View controller was popped")
        }

    }

谢谢大家!

答案 1 :(得分:0)

<强>已更新

如果您想知道导航栏何时弹出一个项目,那么事情就更棘手了,您需要navigationBar:shouldPopItem:。请查看this以获取更多信息。如果您想在pop之前做一些事情,我能想到的最好方法是扩展UINavigationController

@objc public protocol NavigationBarDelegate {
    @objc optional func navigationBarShouldPop() -> Bool }

extension UINavigationController: UINavigationBarDelegate  {

    public func navigationBar(_ navigationBar: UINavigationBar, shouldPop item: UINavigationItem) -> Bool {
        if viewControllers.count < (navigationBar.items?.count)! {
            // When it's being called twice
            return true
        }

        guard let vc = self.topViewController else { return true }
        var shouldPop = true

        if vc.responds(to: #selector(vc.navigationBarShouldPop)) {
            shouldPop = vc.navigationBarShouldPop()
        }

        if shouldPop {
            DispatchQueue.main.async {
                self.popViewController(animated: true)
            }
        } else {
            DispatchQueue.main.async {
                // To fix the problem of back button disabled
                let dimmed = navigationBar.subviews.flatMap {$0.alpha < 1 ? $0 : nil}
                UIView.animate(withDuration: 0.25, animations: {
                    dimmed.forEach { $0.alpha = 1 }
                })
            }
        }

        return false
    }
}

然后,如果你想在视图控制器弹出之前做任何事情

class VC3: UIViewController, NavigationBarDelegate {
    func navigationBarShouldPop() -> Bool {
        // Do whatever you want here
        return true
    }
}

<强> ORIGINAL

假设您在vc3,当然您现在使用NavigationController。应该有3种情况:

(1)你想回到vc2

dismiss(animated: true, completion: nil)

(2)您想要导航到新的视图控制器(vc4)并使用界面构建器

let vc4 = VC4(nibName: "VC4View", bundle: nil)
navigationController?.pushViewController(vc4, animated: true)

(3)你想要在堆栈上弹出一个视图,而不是前一个视图。例如,vc1

// If the destination view controller is already on the stack, just pop to it
for item in (navigationController?.viewControllers)! {
    if item.isKind(of: VC1.self)  {
       _ = navigationController?.popToViewController(item, animated: true)
    }
}

答案 2 :(得分:0)

如果ViewDidLoad调用了,那么你正在推动一个新的ViewController,否则ViewController已经在导航控制器堆栈中,你将转到之前的ViewController。