Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/118.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
什么';iOS Swift应用程序的正确导航结构是什么?_Ios_Swift_Storyboard - Fatal编程技术网

什么';iOS Swift应用程序的正确导航结构是什么?

什么';iOS Swift应用程序的正确导航结构是什么?,ios,swift,storyboard,Ios,Swift,Storyboard,我正在创建一个应用程序,如下所示 发射屏幕 a。如果已查看并接受“入门”屏幕,则打开主应用程序 b。如果未查看/接受,则显示“入门”,然后在接受后显示主应用程序 “入门”屏幕非常独立,因此我为它们创建了一个故事板,而主应用程序将通过编程方式创建 (2)的逻辑应该在哪里?我在考虑创建一种UINavigationController,它位于两组屏幕之上,可以决定显示什么。或者,我打算只启动主应用程序VC,让逻辑显示“入门”作为一种模式在那里直播 关于最佳实践有什么建议吗?请使用AppDe

我正在创建一个应用程序,如下所示

  • 发射屏幕
    • a。如果已查看并接受“入门”屏幕,则打开主应用程序
    • b。如果未查看/接受,则显示“入门”,然后在接受后显示主应用程序
“入门”屏幕非常独立,因此我为它们创建了一个故事板,而主应用程序将通过编程方式创建

(2)的逻辑应该在哪里?我在考虑创建一种UINavigationController,它位于两组屏幕之上,可以决定显示什么。或者,我打算只启动主应用程序VC,让逻辑显示“入门”作为一种模式在那里直播


关于最佳实践有什么建议吗?

请使用AppDelegate.h/SceneDelegate.h中的代码启动 仅供参考,我相信您仍然可以混合使用故事板ViewController和代码ViewController。但是我建议只使用一种样式(在本例中,以编程方式编写代码ViewController)

然后使用UserDefault存储用户是否单击“开始”


没有明确的答案。但是,您可以尝试稍微预测一下您的需求:

  • 如果登录屏幕是唯一以这种方式显示的内容,则可以在
    AppDelegate
    或主视图控制器中放置一些代码
  • 如果您计划在某些版本后显示此类屏幕(例如显示新功能),则可以使用某种模式机制来显示可以取消的全屏模式
无论您选择何种解决方案:

尝试将代码保存在适当的类或结构中:决定显示哪个屏幕以及如何创建视图控制器的逻辑必须在适当的类或结构中。这种逻辑既不属于
AppDelegate
也不属于主视图控制器-顺便说一句,这就是如何结束庞大而混乱的视图控制器

为了满足您的需要,您可以在同一类型的多个实体之间进行选择,您可以查看。它是一种封装逻辑以创建实体的通用结构。您可以将其设计为在控制器之间进行选择:

class RootViewControllerFactory{
var rootViewController:UIViewController{
如果应在BoardingScreen()上显示{
返回生成BoardingScreen()
}否则{
返回generateHomeScreen()
}
}
私有函数应显示在BoardingScreen()->Bool{
//您的逻辑将决定是否显示它。
}
func generateOnboardingScreen()->UIViewController{
//从你的故事板加载它
}
func generateHomeScreen()->UIViewController{
//以编程方式加载它
}
}
然后,您的
AppDelegate
可以使用适当的视图控制器,但代码不会与加载代码混淆。这使得阅读更容易:

func应用程序(application:UIApplication,didFinishLaunchingWithOptions launchOptions:[UIApplicationLaunchOptions:[UIApplicationLaunchOptions:Any]?)->Bool{
self.window=UIWindow(框架:UIScreen.main.bounds)
self.window?.rootViewController=RootViewControllerFactory().rootViewController
self.window?.makeKeyAndVisible()
返回真值
}

使用此解决方案,当Onboard view controller关闭时,您可以调用工厂的
generateHomeScreen()
函数来获取主屏幕并切换到主屏幕。

谢谢!顺便说一句,你为什么不把故事板VC和代码VC结合起来呢?仅仅是复杂性或其他原因?还有,你会如何处理被解雇的介绍VC来启动主应用程序?在介绍VC或其他地方委托的按钮点击操作中?1.为什么不混合?没有好坏之分?坚持一种风格,并使其易于维护。在我的情况下,我在这个应用程序中使用MVVM+RxSwift体系结构,我使用Xib进行查看。2.如何取消introVC?无需排除,只需在此处替换keywindow中的根viewController即可。navigator.switchRoot是我用来解耦导航逻辑的导航器方法。下面我简单地为keywindow替换根viewController,对此进行了深入的探讨,并发现了这篇建议不替换根VC的文章,而是使用容器根VC。我想我也可以将显示内容的逻辑放在根VC中,或者让工厂对其进行抽象:你是对的,这也是一个解决方案:拥有一个可以选择显示内容的包含VC。我所看到的唯一丑陋的部分是,你将永远拥有这个包含VC的网站,即使你知道你将永远不再需要它。如果要避免切换
rootViewController
,还可以移动
homeViewController
中的逻辑,并在主视图顶部加载加载VC(全屏模式解决方案)。
        // 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()))
    }