viewDidLoad 调用两次,使用导航控制器

viewDidLoad called twice, using navigation controller

我在 ViewController 上的 ViewDidLoad 方法被调用了两次,但仅在特定情况下被调用。我需要展示两个视图控制器,一个是用户未登录,另一个是用户已登录。我正在使用故事板,并将导航控制器设置为其中的初始视图控制器。

在我的 AppDelegate didFinishLaunchingWithOptions 方法中,我已经使用如下所需的控制器填充了 ViewControllers 数组

let storyboard = UIStoryboard(name: "Main", bundle: nil)
let navigationController = storyboard.instantiateViewController(withIdentifier: "navController") as! UINavigationController
if UserDefaults.standard.object(forKey: USERID) != nil {
    viewController = storyboard.instantiateViewController(withIdentifier: "HomeVC_ID") as! HomeVC
} 
else {
    viewController = storyboard.instantiateViewController(withIdentifier: "LoginVC_ID") as! LoginVC
}
navigationController.viewControllers = [viewController] as! [UIViewController]
self.window?.rootViewController = navigationController
self.window?.makeKeyAndVisible()

ViewDidLoad HomeVC 中的方法被调用了两次,而 LoginVC.

中只调用了一次

我已经尝试搜索文章 viewDidLoad is called twice and viewDidLoad getting called twice on rootViewController at launch 但无法解决问题。

当您从故事板创建导航视图控制器时,它已经包含它的 rootViewController(一定不要与 UIWindowrootViewController 混淆)。我猜这是你的 HomeVC(在情节提要中)。所以,故事板魔术已经创建了 HomeVC,您不必在 didFinishLaunchingWithOptions.

中手动创建它

如果您已在项目s/target 的属性中将故事板指定为主界面,则在didFinishLaunchingWithOptions 中不需要任何创建代码,只需让框架发挥作用即可。

如果您想以编程方式执行此操作,那么 - 在情节提要中 - 您应该删除导航控制器,然后在 didFinishLaunchingWithOptions 中手动创建(而不是通过 instantiateViewController)。您还可以在此处添加适当的根视图控制器(从情节提要中实例化),可能像这样:

let storyboard = UIStoryboard(name: "Main", bundle: nil)

if UserDefaults.standard.object(forKey: USERID) != nil {
    viewController = storyboard.instantiateViewController(withIdentifier: "HomeVC_ID") as! HomeVC
} else {
    viewController = storyboard.instantiateViewController(withIdentifier: "LoginVC_ID") as! LoginVC
}
let navigationController = UINavigationController(rootViewController:viewController)
self.window?.rootViewController = navigationController
self.window?.makeKeyAndVisible()

我建议不要在应用程序委托中执行任何手动转场或加载视图控制器。在 LoginView 的 viewDidLoad 中使用以下代码(希望这始终是您的应用程序的根视图)。

使用segue登录homeview。

if UserDefaults.standard.object(forKey: USERID) != nil {
     self.performSegue(withIdentifier: "HomeViewIdentifier", sender: self)
}

考虑到 HomeViewIdentifiersegueId 对于 LoginViewHomeView。 为什么我建议这样做是因为您需要在用户注销时返回 loginView。如果您将 homeView 设置为 rootview 那么在注销的情况下您将去哪里。