Closed. This question needs to be more focused 。它目前不接受答案。












想改善这个问题吗?更新问题,使其仅通过 editing this post 关注一个问题。

3年前关闭。



Improve this question




我有一个应用程序,该应用程序在第一次启动时要求用户 登录或创建一个 帐户。 (虽然通常不建议这样做,但这是一个非常具体的用例。)

此外,如果他们已经登录,更新应用程序时 我想向他们展示一个屏幕,告诉他们新功能(如 iOS12 中的笔记、照片和音乐)。

我遇到的问题是,在 AppDelegate 中更改“window”的“rootViewController”时,应用程序出现故障,我可以看到主 View Controller 一瞬间,然后才可以看到载入 View Controller 。

有没有办法避免这种情况?这个逻辑可以封装在ViewControllers 或者AppDelegate 中吗?

是否有一种机制可以用于一个或多个不依赖于多个实现的场景?

最佳答案

首先,当您处理多个流程时,这是可以有效使用 Storyboard的地方。默认情况下,您的应用程序使用 Main.storyboard 作为您的主要流程。您的入职/替代流程可以包含在辅助 Storyboard中,例如。 Onboarding.storyboard
这有许多优点:

  • 在一个开发团队中,每个用户流上的工作可以分开
  • 更清晰的源代码控制 (git) o​​jit_rli
  • 关注点分离

  • 当您的应用程序启动时,您可以确定应该呈现哪个流。这个逻辑可以包含在你的 AppDelegate 中:
    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
        let isFirstRun = true // logic to determine goes here
        if isFirstRun {
            showOnboarding()
        }
        return true
    }
    

    为了展示 Onboarding 流程,值得考虑您希望如何处理在使用它的人完成旅程后关闭它的体验,并且这对于您尝试创建的内容在语义上是正确的。

    方法:

    两种主要方法是:
  • 交换 App 主窗口的根 View Controller
  • 将入职流程呈现为模态旅程,与主要流程重叠。

  • 这个实现应该包含在 AppDelegate 的扩展中。

    选项 1:交换根 View Controller (好)

    切换根 View Controller 有一些好处,尽管转换选项仅限于 UIViewAnimationOptions 支持的选项,因此根据您希望如何在流之间转换可能意味着您必须实现自定义转换 - 这可能很麻烦。

    您可以通过简单地设置 UIApplication.shared.keyWindow.rootViewController 来显示入职流程

    通过使用 UIView.transition(with:) 并将过渡样式作为 UIViewAnimationOptions 传递来处理解雇,在本例中为 Cross Dissolve。 (也支持翻转和 curl )。

    您还必须在转换回主 View 之前设置主 View 的框架,因为您是第一次实例化它。
    // MARK: - Onboarding
    
    extension AppDelegate {
    
        func showOnboarding() {
            if let window = UIApplication.shared.keyWindow, let onboardingViewController = UIStoryboard(name: "Onboarding", bundle: nil).instantiateInitialViewController() as? OnboardingViewController {
                onboardingViewController.delegate = self
                window.rootViewController = onboardingViewController
            }
        }
    
        func hideOnboarding() {
            if let window = UIApplication.shared.keyWindow, let mainViewController = UIStoryboard(name: "Main", bundle: nil).instantiateInitialViewController() {
                mainViewController.view.frame = window.bounds
                UIView.transition(with: window, duration: 0.5, options: .transitionCrossDissolve, animations: {
                    window.rootViewController = mainViewController
                }, completion: nil)
            }
        }
    }
    

    选项 2:以模态呈现替代流程(更好)

    在最直接的实现中,入职流程可以简单地呈现在模态上下文中,因为从语义上讲,用户处于单次旅程中。



    模态呈现允许在旅程结束时关闭的简单选项,几乎没有交换 Controller 的麻烦。

    标准方式也支持自定义转换,因为它使用 ViewController.present() API:
    // MARK: - Onboarding
    
    extension AppDelegate {
    
        func showOnboarding() {
            if let window = window, let onboardingViewController = UIStoryboard(name: "Onboarding", bundle: nil).instantiateInitialViewController() as? OnboardingViewController {
                onboardingViewController.delegate = self
                window.makeKeyAndVisible()
                window.rootViewController?.present(onboardingViewController, animated: false, completion: nil)
            }
        }
    
        func hideOnboarding() {
            if let window = UIApplication.shared.keyWindow {
                window.rootViewController?.dismiss(animated: true, completion: nil)
            }
        }
    }
    

    关于Swift:在呈现主要和替代(登录/入职)流程时出现视觉故障?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/45321570/

    10-13 03:59