18

Before changes in UIKit iOS 13 how I can set rootViewController at SceneDelegate?

class SceneDelegate: UIResponder, UIWindowSceneDelegate {

    var window: UIWindow?


    @available(iOS 13.0, *)
    func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
        guard let _ = (scene as? UIWindowScene) else { return }

    }
Vinicius Mangueira
  • 309
  • 1
  • 2
  • 9

4 Answers4

41

FYI since SwiftUI doesn't use storyboards if you just make a new SwiftUI project it will give you the code; all you need to do is replace the UIHostingViewController with your desired root VC like this:

class SceneDelegate: UIResponder, UIWindowSceneDelegate {

  var window: UIWindow?

  func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {

    if let windowScene = scene as? UIWindowScene {
        let window = UIWindow(windowScene: windowScene)
        window.rootViewController = MyRootViewController()
        self.window = window
        window.makeKeyAndVisible()
    }
  }
Josh Homann
  • 15,933
  • 3
  • 30
  • 33
14

If you ever find yourself needing to access the window from the delegate (both iOS12 & iO13)to change the rootviewcontroller here's a couple of extensions I use:

   extension UIViewController {
        var appDelegate: AppDelegate {
        return UIApplication.shared.delegate as! AppDelegate
    }
    
    var sceneDelegate: SceneDelegate? {
        guard let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene,
            let delegate = windowScene.delegate as? SceneDelegate else { return nil }
         return delegate
    }
}

extension UIViewController {
    var window: UIWindow? {
        if #available(iOS 13, *) {
            guard let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene,
                let delegate = windowScene.delegate as? SceneDelegate, let window = delegate.window else { return nil }
                   return window
        }
        
        guard let delegate = UIApplication.shared.delegate as? AppDelegate, let window = delegate.window else { return nil }
        return window
    }
}
Larry Mickie
  • 441
  • 4
  • 9
1

If you don't need to support multi window support just ignore it. I follow up this answer.

When you start new project with it's automatically creates manifest and SceneDelegate class. After ignore multi window support, you can use app delegate window again like before.

Gürhan KODALAK
  • 570
  • 7
  • 20
0

Like this:

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 }

        let rootVC = self.window?.rootViewController 
    }
    // ... the rest of SceneDelegate
}

As seen here.

Marina Aguilar
  • 1,151
  • 9
  • 26