【问题标题】:Replacing current Storyboard with a new Storyboard in iOS在 iOS 中用新的 Storyboard 替换当前的 Storyboard
【发布时间】:2018-05-09 16:21:45
【问题描述】:

我正在构建一个应用程序,我决定在多个 Storyboard 文件中构建我的用户界面。每个 Storyboard 都是一组相似的动作。例如,LogInStoryboard 包含用于登录和注册用户的视图。

我在导航到新的 Storyboard 并关闭所有以前的视图控制器以自行清理时遇到了一些问题。

这是我的数据流:

1) 应用程序启动到登录视图。根视图控制器是LogInViewController,它位于LogInStoryboard

2) 用户点击注册按钮召唤模态RegistrationViewController,也住在LogInStoryboard

3) 用户完成注册并自动登录。

此时,视图控制器堆栈为[LogInViewController, RegistrationViewController]。注册后,用户会自动登录,所以我想导航到他们的主屏幕,HomeViewController。然而,HomeViewController 存在于另一个 Storyboard HomeStoryboard 中。

我想同时关闭LogInViewControllerRegistrationViewController,然后我想从HomeStoryboard 实例化HomeViewController 并呈现它。这样我就有了一个简单的视图控制器堆栈,LogInStoryboard 视图控制器都可以被释放。

实现这种流程的最佳方式是什么?还是我应该如此担心那些旧的视图控制器?

【问题讨论】:

  • 这听起来确实像您在寻找协调器模式或流控制器。即使您可能必须更改代码,但它的定义是值得的。更好地通过您的应用程序和代码进行操作!

标签: ios swift storyboard uikit


【解决方案1】:

通常情况下,您的登录流程几乎充当一个完全独立的应用程序,其唯一功能是验证用户身份并将用户信息写入您的数据库。在这种情况下,当您完成登录而不是执行 segue 时,您想要做的是将整个视图层次结构替换为 HomeViewController。为此,您只需调用UIApplication.shared.keyWindow! = UIStoryboard(name: "HomeStoryboard", bundle: nil).instantiateInitialViewController()(假设您将HomeViewController 设为初始视图控制器)。当然,这没有动画,而且有点难看,所以你想使用UIView.transition(with:duration:options:animations:completion:) 来为更改设置动画。示例:

    UIView.transition(with: UIApplication.shared.keyWindow!, duration: 0.25, options: .transitionCrossDissolve,
                      animations: {
                        UIApplication.shared.keyWindow!.rootViewController = UIStoryboard(name: "HomeStoryboard", bundle: nil).instantiateInitialViewController()
    })

【讨论】:

  • 我曾考虑过这样做,但出于几个原因我不喜欢它。首先,它不会导致两个视图控制器都调用deinit。我想这是因为他们没有被适当地解雇。其次,但不太重要的是,我不喜欢手动修改keyWindow
  • 看起来我忘记在keyWindow.rootViewController 上调用dismiss(animated:completion:) 这样做会解散所有呈现的视图控制器并导致它们像我想要的那样调用deinit。我认为这个解决方案对我有用。
【解决方案2】:

Swift 4.0

我将从 HomeViewController 作为初始视图控制器开始。 然后从那里创建 LogInViewController

if shouldLogin {
    let storyboard = UIStoryboard(name: "LogInStoryboard", bundle: nil)
    let loginVCtrl = storyboard.instantiateViewController(withIdentifier: "yourLogInViewControllerID")
    present(loginVCtrl, animated: true)
}

在您的用户完成登录/注册过程后,您可以致电:

dismiss(animated: true)

所以你的 ViewController 堆栈看起来像:

  1. [HomeViewController]
  2. [HomeViewController、LogInViewController]
  3. [HomeViewController]

【讨论】:

  • 我确实喜欢这个解决方案作为一个概念。不过,这需要对我的应用程序架构进行一些修改。我一定会把它记在脑海里;它最终可能是更优雅的解决方案。
  • 很高兴为您提供帮助。请不要忘记点击答案左侧的复选标记来接受最能回答您问题的答案。
【解决方案3】:

appdelegate 中的HomeViewController 设置为navigationcontroller 并将navigationcontroller 设置为rootviewcontroller

注意:这两个操作都在 appdelegate 中执行

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-06-17
    • 2015-07-29
    • 2016-01-26
    • 2017-08-10
    • 1970-01-01
    • 2013-04-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多