是否可以以编程方式创建展开转场?

Posted

技术标签:

【中文标题】是否可以以编程方式创建展开转场?【英文标题】:Is it possible to create unwind segues programatically? 【发布时间】:2019-05-23 17:15:10 【问题描述】:

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

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

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

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

而转场将是一个放松转场。然后,每当请求失败时,我都会调用视图控制器的 unwindToLoginScreen 方法。

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

到目前为止,我认为理想的计划是能够以编程方式创建展开转场,而不是使用情节提要。所以,我的unwindToLoginScreen() 扩展方法默认可以在任何新的视图控制器中工作。比如:

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

有可能做这样的事情吗?

【问题讨论】:

有可能,我过去也这样做过。我不记得怎么了:P 【参考方案1】:

您不能在代码中创建转场,但可以弹出到UINavigationController 的堆栈的根:

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

如果你想弹出一个非root的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:  $0 is LoginViewController ) 
    self.navigationController?.popToViewController(loginVC, animated: true)

【讨论】:

这太棒了。而且...假设视图控制器不完全是根视图控制器...我可以弹出到堆栈中的任意控制器吗? 是的,您可以指定要弹出的控制器,例如:self.navigationController?.popToViewController(self.navigationController!.viewControllers[1], animated: true)。这将弹出到堆栈中的第二个 viewController。 这对我帮助很大!

以上是关于是否可以以编程方式创建展开转场?的主要内容,如果未能解决你的问题,请参考以下文章

Swift 以编程方式创建一个 unwind segue

展开后执行segue

Swift 以编程方式设置转场

是否可以在情节提要中定义“通用”展开转场?

加速转场和放松转场

在单元测试中以编程方式执行 Unwind Segue