提问者:小点点

Swift:两种视图控制器


为问题的模棱两可表示歉意; 我在这里尽量解释得更清楚些。

我在AppDelegate.swift中有一些执行条件导航的代码; 如果用户已登录(因此CurrentUser不是Nil),则应用程序将在View中启动,这是Main情节提要中的一个视图控制器。 否则,如果用户没有登录,应用程序将在welcome中启动,这是auth情节提要中的一个视图控制器。

以下是我在AppDelegate.swiftViewController.swift(即View)和WelcomeViewController中的代码。

注意:

View是我为ViewController设置的情节提要ID; 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.")
    }

}

该应用程序是新安装在模拟器上的,因此应该没有CurrentUser(在调试时,证明是真的)。 因此,我希望在控制台中看到以下输出:

WelcomeViewController presented.

相反,它显示在控制台中:

WelcomeViewController presented.
ViewController presented.

到目前为止,我认为问题可能是由于main情节提要是自项目创建以来的默认情节提要集这一事实引起的。 因此,我尝试取消选中两个视图控制器的‘初始视图控制器’复选框。 正如我所预料的那样,下面显示了以下内容:

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?

如何确保ViewController不出现并替换WelcomeViewController? 感谢所有的帮助,谢谢!


共2个答案

匿名用户

为什么不将WelcomeViewController设置为“初始视图控制器”并将其viewDidLoad代码替换为AppDelegate文件,然后:

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()
            }
        } 
    }

}

如果要从AppDelegate设置视图控制器,也可以查看以下内容:

编辑:您可以使用UINavigationController作为初始视图控制器,如以下答案所示:

在appdelegate-swift中设置初始viewcontroller,然后您只需在此处设置正确的view controller:

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

匿名用户

我设法找到了我现在面临的问题的解决办法。 代码上面有两个错误,我在这里解释一下:

Xcode11与iOS13一起推出了SceneDelegate.swift。 我应该将上面的代码放在SceneDelegate.swift中,而不是AppDelegate.swift中; 因为我没有这样做,代码并没有像我所希望的那样运行在运行iOS13.5的模拟器。

以下是我在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()
            }
        }
    }

}

在我上面的代码中,有一个错误行导致创建了一个新的UIWindow:

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()
    }
}

我希望这对其他面临这个问题的人有帮助!