简体   繁体   English

Swift:展示了两个视图控制器

[英]Swift: Two View Controllers presented

Apologies for the ambiguity of the question;为问题的模棱两可道歉; I'll try to explain clearer here.我将尝试在这里更清楚地解释。

The Problem问题

I have some code in AppDelegate.swift that performs conditional navigation;我在AppDelegate.swift中有一些执行条件导航的代码; if the user is signed in (and therefore currentUser is not nil ), the app will start in View , a View Controller in the Main storyboard.如果用户已登录(因此currentUser不是nil ),应用程序将在View中启动,即Main storyboard 中的 View Controller。 Else, if the user isn't signed in, the app will start in Welcome , a View Controller in an Auth storyboard.否则,如果用户未登录,应用程序将在Welcome中启动,在Auth storyboard 中查看 Controller。

The following is my code from AppDelegate.swift , ViewController.swift (which is View ), and WelcomeViewController .以下是来自AppDelegate.swiftViewController.swift (即View )和WelcomeViewController的代码。

Note:笔记:

View is the Storyboard ID I set for ViewController ; View是我为ViewController设置的 Storyboard ID; Welcome is the Storyboard ID I set for WelcomeViewController . Welcome是我为 WelcomeViewController 设置的WelcomeViewController ID。

AppDelegate.swift

import UIKit
import Firebase

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {

        // Configures the Firebase library.
        FirebaseApp.configure()

        // Performs conditional navigation on the condition of currentUser's status.
        self.window = UIWindow(frame: UIScreen.main.bounds)
        let user = Auth.auth().currentUser
        if user != nil {
            let storyboard = UIStoryboard(name: "Main", bundle: nil)
            let rootViewController = storyboard.instantiateViewController(identifier: "View")
            window?.rootViewController = rootViewController
            UIView.animate(withDuration: 0.5) {
                self.window?.makeKeyAndVisible()
            }
        } else {
            let storyboard = UIStoryboard(name: "Auth", bundle: nil)
            let rootViewController = storyboard.instantiateViewController(identifier: "Welcome")
            window?.rootViewController = rootViewController
            UIView.animate(withDuration: 0.5) {
                self.window?.makeKeyAndVisible()
            }
        }

        return true
    }

}

ViewController.swift

import UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view.
        print("ViewController presented.")
    }

}

WelcomeViewController.swift

import UIKit

class WelcomeViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view.
        print("WelcomeViewController presented.")
    }

}

Expectations期望

The app is freshly installed on the Simulator, and therefore there should be no currentUser (and upon debugging, proves to be true).该应用程序是新安装在模拟器上的,因此应该没有currentUser (并且在调试时证明是真的)。 Therefore, I'd expect to see this as the output in the Console:因此,我希望在控制台中将其视为 output:

WelcomeViewController presented.

Instead, this shows up in the Console:相反,这会显示在控制台中:

WelcomeViewController presented.
ViewController presented.

Attempts尝试

So far, I thought that the problem might have arised from the fact that Main storyboard is the default Storyboard set since the creation of the project.到目前为止,我认为问题可能是由于Main storyboard 是自项目创建以来设置的默认 Storyboard 。 Therefore, I tried unchecking the 'Initial View Controller' checkbox for the two View Controllers.因此,我尝试取消选中两个视图控制器的“初始视图控制器”复选框。 Just like I'd expected, the following appears instead:就像我预期的那样,出现了以下内容:

WelcomeViewController presented.
2020-06-20 11:39:38.724658+0800 AppName[11439:237509] [WindowScene] Failed to instantiate the default view controller for UIMainStoryboardFile 'Main' - perhaps the designated entry point is not set?

What should I do to make sure that ViewController doesn't appear and replace WelcomeViewController ?我应该怎么做才能确保ViewController不出现并替换WelcomeViewController All help is appreciated, thanks!感谢所有帮助,谢谢!

why not set WelcomeViewController as your 'Initial View Controller' and replace its viewDidLoad code with AppDelegate file then:为什么不将 WelcomeViewController 设置为您的“初始视图控制器”,然后用 AppDelegate 文件替换其 viewDidLoad 代码:

class WelcomeViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view.
        print("WelcomeViewController presented.")

        let user = Auth.auth().currentUser
        if user != nil {
            let storyboard = UIStoryboard(name: "Main", bundle: nil)
            let rootViewController = storyboard.instantiateViewController(identifier: "View")
            window?.rootViewController = rootViewController
            UIView.animate(withDuration: 0.5) {
                self.window?.makeKeyAndVisible()
            }
        } 
    }

}

you can also look this if you want to set the view controller from AppDelegate:如果你想从 AppDelegate 设置视图 controller,你也可以看看这个:

EDIT: you can use a UINavigationController as your initial view controller as indicated in this answer:编辑:您可以使用 UINavigationController 作为您的初始视图 controller,如本答案所示:

set initial viewcontroller in appdelegate - swift then you just need to set the correct view controller here: 在 appdelegate 中设置初始视图控制器 - swift然后您只需在此处设置正确的视图 controller :

navigationController.viewControllers = [rootViewController]
self.window?.rootViewController = navigationController

Solution解决方案

I managed to find the solution to the issue that I'm facing here.我设法找到了我在这里面临的问题的解决方案。 There are two mistakes above in the code, and I'll explain it here:上面的代码有两个错误,我在这里解释一下:

Mistake 1: Code should be in SceneDelegate instead of AppDelegate (iOS 13)错误一:代码应该在SceneDelegate而不是AppDelegate (iOS 13)

Xcode 11, along with the release of iOS 13, introduced SceneDelegate.swift . Xcode 11,随着 iOS 13 的发布,引入了SceneDelegate.swift I was supposed to put my code above in SceneDelegate.swift instead of AppDelegate.swift ;我应该把我的代码放在SceneDelegate.swift而不是AppDelegate.swift because I didn't do this, the code hadn't worked as I'd hoped for my Simulator, which was running iOS 13.5.因为我没有这样做,所以代码没有像我希望的那样运行在运行 iOS 13.5 的模拟器上。

Here's my rectified code in SceneDelegate.swift :这是我在SceneDelegate.swift中的更正代码:

import UIKit
import Firebase

class SceneDelegate: UIResponder, UIWindowSceneDelegate {

    var window: UIWindow?

    func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
        // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`.
        // If using a storyboard, the `window` property will automatically be initialized and attached to the scene.
        // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead).
        guard let _ = (scene as? UIWindowScene) else { return }

        // Performs conditional navigation on the condition of currentUser's status.
        let user = Auth.auth().currentUser
        if user != nil {
            let storyboard = UIStoryboard(name: "Main", bundle: nil)
            let rootViewController = storyboard.instantiateViewController(identifier: "View")
            window?.rootViewController = rootViewController
            UIView.animate(withDuration: 0.5) {
                self.window?.makeKeyAndVisible()
            }
        } else {
            let storyboard = UIStoryboard(name: "Auth", bundle: nil)
            let rootViewController = storyboard.instantiateViewController(identifier: "Welcome")
            window?.rootViewController = rootViewController
            UIView.animate(withDuration: 0.5) {
                self.window?.makeKeyAndVisible()
            }
        }
    }

}

Mistake 2 (Important:): Definition of new UIWindow错误2(重要:):新UIWindow的定义

In my code above, there was a faulty line which caused the creation of a new UIWindow :在我上面的代码中,有一条错误的行导致创建了一个新的UIWindow

self.window = UIWindow(frame: UIScreen.main.bounds)

By removing this line of code, the problem was resolved.通过删除这行代码,问题得到解决。 Here's the rectified code:这是修正后的代码:

let user = Auth.auth().currentUser
if user != nil {
    let storyboard = UIStoryboard(name: "Main", bundle: nil)
    let rootViewController = storyboard.instantiateViewController(identifier: "View")
    window?.rootViewController = rootViewController
    UIView.animate(withDuration: 0.5) {
        self.window?.makeKeyAndVisible()
    }
} else {
    let storyboard = UIStoryboard(name: "Auth", bundle: nil)
    let rootViewController = storyboard.instantiateViewController(identifier: "Welcome")
    window?.rootViewController = rootViewController
    UIView.animate(withDuration: 0.5) {
        self.window?.makeKeyAndVisible()
    }
}

I hope this helps anyone else facing this issue!我希望这可以帮助其他面临这个问题的人!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM