迅速:提出主要和替代(登录/入职)流程时出现视觉故障?

cle*_*bit 3 user-experience storyboard appdelegate swift

我有一个应用程序,要求该人在首次启动该应用程序时登录或创建帐户。(尽管通常不建议这样做,但这是一个非常特定的用例。)

此外,如果他们已经登录,则在更新应用程序时,我想向他们显示一个屏幕,告诉他们新功能(如iOS12中的Notes,Photos和Music)。

我遇到的问题是在AppDelegate中更改“ window”的“ rootViewController”时,应用程序出现故障,并且在入职视图控制器变得可见之前,我可以瞬间看到主视图控制器。

有办法避免这种情况吗?可以将此逻辑封装在ViewController或AppDelegate中吗?

在不依赖多个实现的情况下,是否有一种我可以用于这些场景中的一个或多个的单一机制?

cle*_*bit 10

首先,当您处理多个流时,可以在这里有效使用情节提要。默认情况下,您的应用程序Main.storyboard用于主要流程。您的入职/替代流程可以包含在辅助情节提要中,例如。Onboarding.storyboard

这具有许多优点:

  • 在开发人员团队中,每个用户流上的工作可以分开
  • 更清晰的源代码管理(git)
  • 关注点分离

应用启动时,您可以确定应显示哪个流程。逻辑可以包含在您的AppDelegate中:

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
    let isFirstRun = true // logic to determine goes here
    if isFirstRun {
        showOnboarding()
    }
    return true
}
Run Code Online (Sandbox Code Playgroud)

为了显示“入职”流程,值得考虑的是,一旦使用它的人完成了旅程,您将如何处理将其解雇的经验,并且从语义上来说,这是您想要创建的东西的正确方法。

方法:

两种主要方法是:

  1. 交换应用程序主窗口的根视图控制器
  2. 将入职流程作为模态旅程呈现,与主流流程重叠。

此实现应包含在AppDelegate的扩展中。

选项1:交换根视图控制器(良好)


切换根视图控制器是有好处的,尽管过渡选项仅限于所支持的过渡选项UIViewAnimationOptions,所以根据您希望在流之间进行过渡的方式,可能意味着您必须实现自定义过渡-这可能很麻烦。

您可以通过简单地设置 UIApplication.shared.keyWindow.rootViewController

通过使用UIView.transition(with:)过渡样式作为来处理解雇UIViewAnimationOptions,在本例中为Cross Dissolve。(还支持翻转和卷发)。

当您第一次实例化主视图时,还必须设置主视图的框架,然后再过渡到主视图。

// 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)
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

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


在最直接的实现中,由于用户在语义上处于单一旅程,因此可以简单地在模式上下文中呈现“入职”流程。

苹果人机界面指南–模式

仅在引起人们注意的关键,必须完成或放弃一项任务才能继续使用该应用程序或保存重要数据时,才考虑创建模式上下文。

模态呈现允许在旅程结束时解雇的简单选择,而几乎没有交换控制器的麻烦。

自定义转换还以标准方式受支持,因为它使用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)
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 可悲的是,这个答案没有更多的赞誉? (2认同)