6

I have manually setup a root view controller for iOS 13 using Xcode 11, Beta 5. Deleted references to main in the deployment info including removing reference to main in info.plist which I never found myself having to do prior to iOS 13. Setup for window is done in SceneDelegate, nested in willConnectTo function. Normally the app would crash if I missed a step. Now I'm getting a blank black screen instead of seeing what my view controller is setup for, say a red background. All of this use to work prior to beta 5.

Have performed erase all content and settings on the simulator. Cleared the build folder and have ran the app on a physical device. Also have used another computer with Xcode 11, beta 5. All results to the same blank black screen. What am I missing?

Here is my manual setup for root view controller in SceneDelegate file nested in willConnectTo function:

let viewCon = ViewController()
window = UIWindow(frame: UIScreen.main.bounds)
window?.rootViewController = viewCon
window?.makeKeyAndVisible()
Adnan
  • 65
  • 1
  • 6

3 Answers3

29

To ensure you see your root view controller in iOS 13 when everything is done programmatically, you must do the following:

In the scene delegate, you must create the window instance and the root view controller:

class SceneDelegate: UIResponder, UIWindowSceneDelegate {
    var window: UIWindow?

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

        // Create the root view controller as needed
        let vc = ViewController()
        let nc = UINavigationController(rootViewController: vc)

        // Create the window. Be sure to use this initializer and not the frame one.
        let win = UIWindow(windowScene: winScene) 
        win.rootViewController = nc
        win.makeKeyAndVisible()
        window = win
    }
}

Your Info.plist has to have the "Application Scene Manifest" entry. Below it should be the "Enable Multiple Windows" entry. Set to YES or NO as appropriate to your app. Optionally you should also have the "Scene Configuration" entry.

All of these entries are added by Xcode when you check the "Supports multiple windows" setting on the General tab of your target. This will default the "Enable Multiple Windows" entry to YES so you can change that to NO if you want scenes but not multiple windows.

rmaddy
  • 314,917
  • 42
  • 532
  • 579
  • 1
    Thank you for teaching me this. I can see my root view controller now! – Adnan Aug 11 '19 at 16:24
  • For anyone looking for an updated "Single View App" Xcode template that supports iOS 12 and 13 as well as supporting either a storyboard or an all-code user interface, see https://github.com/rmaddy/XcodeTemplates. – rmaddy Sep 25 '19 at 05:33
  • This. `UIWindow(windowScene: scene)` should be used instead of `UIWindow(frame: scene.coordinateSpace.bounds)` – Nik Jan 07 '21 at 11:57
2
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {

    guard let windowScene = (scene as? UIWindowScene) else { return }

    let window = UIWindow(windowScene: windowScene)
    self.window = window
    let mainstoryboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
    let newViewcontroller:UIViewController = mainstoryboard.instantiateViewController(withIdentifier: "YourVCName") as! YourVCName
    navigationController = UINavigationController(rootViewController: newViewcontroller)
    window.rootViewController = navigationController
    window.makeKeyAndVisible()
}

try this code!! if you are using ios 13 and your xcode is updated then you should set your root view controller in scene delegate instead of app delegate.

Vipin Pareek
  • 236
  • 2
  • 10
  • Please put your answer always in context instead of just pasting code. See [here](https://stackoverflow.com/help/how-to-answer) for more details. – gehbiszumeis Jan 16 '20 at 06:21
0

I faced the same problem by the time, I know someone has solved this issue, however, I just wanna share my approach.

let storyBoard = UIStoryboard(name: "Main", bundle: nil)
let initialViewController = storyBoard.instantiateViewController(withIdentifier: "HomeScreen") as? HomeScreen
self.window?.rootViewController = initialViewController

I used this simple code instead, and it works like a charm : )