我正在创建一个app,工作原理如下
"入门 "屏幕是相当独立的,所以我为它们创建了一个Storyboard,而主应用程序将被程序化地创建。
(2)的逻辑应该放在哪里?我在考虑创建某种UINavigationController,它将位于两组屏幕之上,并可以决定显示什么。或者,我打算直接启动主应用程序VC,让 "Getting Started "的逻辑作为一个模态显示在那里。
请问有什么最佳实践建议吗?
没有明确的答案。不过,你可以试着预测一下自己的需求。
AppDelegate
或在您的主视图控制器中。无论你选择哪种方案。
尽量把你的代码放在一个合适的类或结构中:决定显示什么屏幕和如何创建视图控制器的逻辑必须放在一个合适的类或结构中。这个逻辑也不属于 AppDelegate
也不在你的主视图控制器中--顺便说一句,这就是你如何结束巨大而混乱的视图控制器。
对于你的需求--在多个同类实体之间进行选择--你可以看一看 工厂设计模式. 它是一种常见的结构,封装了创建实体的逻辑。你可以设计它来选择你的控制器。
class RootViewControllerFactory {
var rootViewController: UIViewController {
if shouldDisplayOnboardingScreen() {
return generateOnboardingScreen()
} else {
return generateHomeScreen()
}
}
private func shouldDisplayOnboardingScreen() -> Bool {
// Your logic to decide whether you should display it or not.
}
func generateOnboardingScreen() -> UIViewController {
// Load it from your storyboard
}
func generateHomeScreen() -> UIViewController {
// Load it programmatically
}
}
然后,你的 AppDelegate
可以使用适当的视图控制器,但在加载代码中没有混入代码。这样阅读起来就方便多了。
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
self.window = UIWindow(frame: UIScreen.main.bounds)
self.window?.rootViewController = RootViewControllerFactory().rootViewController
self.window?.makeKeyAndVisible()
return true
}
有了这个方案,当入职视图控制器被解雇时, 你可以调用 "我的名字"。generateHomeScreen()
函数来获取主屏幕并切换到它,在AppDelegate.hSceneDelegate.h中使用代码启动。
在AppDelegate.hSceneDelegate.h中使用代码启动,我相信你仍然可以将故事板ViewController和代码ViewController混合使用,但是我建议只使用一种风格(在这种情况下,代码ViewController是程序化的)。
然后用UserDefault来存储用户是否点击 "开始"。
// Set Root VC
guard let windowScene = (scene as? UIWindowScene) else { return }
window = UIWindow(frame: UIScreen.main.bounds)
window?.windowScene = windowScene
let navigator = Container.shared.resolve(INavigator.self)!
let localStorageService = Container.shared.resolve(ILocalStorageService.self)!
if localStorageService.isKeyExist(key: Configs.KEY_USER) {
navigator.switchRoot(keyWindow: window!, scene: .main(viewModel: MainTabBarViewModel()))
} else {
navigator.switchRoot(keyWindow: window!, scene: .intro(viewModel: IntroViewModel()))
}