如何从 SceneDelegate 模态呈现 ViewController?

How to modally present a ViewController from SceneDelegate?

我有一个 OnboardingViewController 可以从应用程序的设置中以模式样式访问它。

当用户第一次打开应用程序时,我想以相同的模式样式向他展示 OnboardingVC(具有上部标签效果,如下所示:Screenshot)从设置中显示它。

SceneDelegate 设置:

func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
    guard let scene = (scene as? UIWindowScene) else { return }
    window = UIWindow(windowScene: scene)
    let storyboard = UIStoryboard(name: "Main", bundle: nil)
    let controller = storyboard.instantiateViewController(withIdentifier: "OnboardingViewController") as! OnboardingViewController
    window?.rootViewController = controller
    window?.makeKeyAndVisible()
 }

问题是一直全屏显示,顶部没有上面的模态标签效果。

如何解决?

您不能显示 UIViewController(模态或全屏),它是 window 的 rootViewController

要在用户首次打开应用程序时显示引导屏幕,请将主页 Screen/Login 屏幕(或您想要的任何屏幕)设置为 SceneDelegate 中的 rootViewController。然后从 UIViewController 你可以检查用户是否第一次打开应用程序。取决于您可以显示入职屏幕。

您必须将 rootViewController 嵌入到 UINavigationViewController 到 present/push 另一个 UIViewController

SceneDelegate.swift中修改如下代码。

func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
    guard let scene = (scene as? UIWindowScene) else { return }
    window = UIWindow(windowScene: scene)
    let storyboard = UIStoryboard(name: "Main", bundle: nil)
    let controller = storyboard.instantiateViewController(withIdentifier: "HomeViewController") as! HomeViewController
    //embed in UINavigationController
    let navController = UINavigationController(rootViewController: controller)
    window?.rootViewController = navController
    window?.makeKeyAndVisible()
 }

然后在主屏幕中(我假设它是主页ViewController)检查首次打开和显示入职屏幕的状态。

class HomeViewController: UIViewController {
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        let storyboard = UIStoryboard(name: "Main", bundle: nil)
        let controller = storyboard.instantiateViewController(withIdentifier: "OnboardingViewController") as! OnboardingViewController
        controller.modalPresentationStyle = .formSheet
        self.present(controller, animated: true)
    }
}

您可以使用以下代码从应用中的任何位置获取 rootViewController。然后展示任何你想展示的ViewController。

let storyboard = UIStoryboard(name: "Main", bundle: nil)
let controller = storyboard.instantiateViewController(withIdentifier: "OnboardingViewController") as! OnboardingViewController
        controller.modalPresentationStyle = .formSheet
let rootVC = UIApplication.shared.windows.first!.rootViewController
rootVC?.present(controller, animated: true)