从应用程序中的任意点“放松”到特定视图控制器

时间:2017-06-06 20:31:11

标签: ios cocoa-touch uiview uiviewcontroller uinavigationcontroller

我想将用户分流回应用程序的初始“启动画面”(第一个视图控制器),以便应用程序可以有效地“重置”并在离线模式下运行。

通常我会使用展开segue将用户推回到特定的视图控制器,但需要从故事板中明确创建展开segue(如果我理解正确的话)。我需要从应用程序的任何一点有效地解开,我不想为所有的几十个视图控制器添加放松segues。

有没有办法以编程方式执行此操作?你可以动态创建一个展开区吗?

我的第一次尝试是在应用程序的“顶级”UIViewController上递归调用dismiss。它在技术上有效,但感觉就像一个kludge,在屏幕上看起来不太好,并且在每个连续的视图控制器上调用viewDidAppear时会产生各种问题。这是代码。

extension UIApplication {

    var topController: UIViewController? {
        var topController = keyWindow?.rootViewController
        while topController?.presentedViewController != nil {
            topController = topController?.presentedViewController
        }
        return topController
    }

    // Recursively dismiss until some condition is met
    func dismiss(until: @escaping ((UIViewController?)->Bool), completion: (()->Void)?) {
        var proxy: (()->Void) = { }
        let doDismiss: (()->Void) = {
            if !until(self.topController) {
                DispatchQueue.main.async {
                    self.topController?.dismiss(animated: false, completion: proxy)
                }
            } else {
                completion?()
            }
        }
        proxy = doDismiss
        doDismiss()
    }
}

它被称为:

UIApplication.shared.dismiss(until: { (topController) -> Bool in
    return topController is SplashScreenViewController
}, completion: nil)

是否有更简单的解决方案?

1 个答案:

答案 0 :(得分:0)

很抱歉,您无法在代码中创建任何类型的segue,必须在故事板中进行设置。

如何实现所需并返回初始视图控制器取决于您如何设置控制器层次结构。例如,如果您正在使用UINavigationController并且已将所有视图控制器推送到它上,那么您可以只使用popToRootViewController(动画:Bool)。除此之外的任何东西都取决于你可能需要手动处理它。

您可能需要重新考虑视图控制器层次结构。