是否可以通过编程方式创建 unwind segue?

Is it possible to create unwind segues programatically?

我的应用程序有一个导航控制器,其中第一个视图控制器是登录屏幕,所有其他屏幕都被推到顶部。

每当对后端的任何 http 请求 returns 出现 401 错误时,我都想回到登录屏幕。

我的想法是为 ViewController class 添加一个扩展,如下所示:

extension UIViewController {
    func unwindToLoginScreen() {
        performSegue(withIdentifier: loginScreen)
    }
}

并且转场将是展开转场。然后,每当请求失败时,我都会调用视图控制器的 unwindToLoginScreen 方法。

但是,这种方法的问题是我必须记住在故事板上为我添加到项目中的所有新视图控制器创建所述展开转场。

到目前为止,我认为理想的计划是能够以编程方式创建展开转场,而不是使用故事板。因此,默认情况下,我的 unwindToLoginScreen() 扩展方法可以在任何新的视图控制器中使用。类似于:

extension UIViewController {
    func unwindToLoginScreen() {
        let segue = UnwindSegue(identifier: "blablah", segue: LoginViewController.unwindToLoginViewController)
        segue.perform()
    }
}

是否可以这样做?

您无法在代码中创建 segue,但您可以弹出到 UINavigationController 堆栈的根:

func returnToLoginScreen() {
    self.navigationController?.popToRootViewController(animated: true)
}

如果你想弹出一个不是根的viewController,你可以在UINavigationController管理的viewController数组中找到它,然后调用popToViewController:

// pop to second viewController in the stack
self.navigationController?.popToViewController(self.navigationController!.viewControllers[1], animated: true)

... 或按类型搜索 ViewController

if let loginVC = self.navigationController?.viewControllers.first(where: { [=12=] is LoginViewController }) {
    self.navigationController?.popToViewController(loginVC, animated: true)
}