Skip to content

XCode 11 – New Project Without a Storyboard

Heads up: the way to start a new project without a Storyboard (i.e. all UI in code) has changed in XCode 11. I just wasted an age trying to work out what was happening, so here’s a quick summary for anyone else scratching their head…

The key to it all is that it doesn’t happen in the AppDelegate any more. All the magic takes place in the Scene Delegate. That Apple had split out the functionality of AppDelegate was one of those changes I heard many people mention in all the “What’s new in …” posts, but it’s importance never really sank in. I wonder what other impact it’ll have down the line?

Getting it all started

  • Delete Main.Storyboard from your project. Yep, that’s not changed 🙂
  • Go to the new SceneDelegate class and find
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions)
  • This is where you’ll do most of your work. Also note that the window variable has teleported from AppDelegate to this class – you’re going to need this in a second.
  • This function is currently throwing away the WindowScene as it is geared up to work with the Storyboard. You’re going to need this, so replace the underscore with a suitable parameter name. windowScene works for me:
guard let windowScene = (scene as? UIWindowScene) else { return }
  • Create yourself a Window using the window scene to define it’s size – this basically tells it to use all available space:
window = UIWindow(frame: windowScene.coordinateSpace.bounds)
  • And then, feeling somewhat counter-intuitive, assign window scene to the windows you have just created:
window?.windowScene = windowScene
  • You’ll also need something to display at startup as the initial view controller. Nothing new here, so to quickly knock something up I’ll create a basic tab bar, but this could be as simple as an empty view controller just to get things going:
let tabBarController = UITabBarController()
let vc1 = UIViewController()
vc1.view.backgroundColor = .systemTeal
let tabBar1 = UITabBarItem(tabBarSystemItem: .downloads, tag: 0)
vc1.tabBarItem = tabBar1
let vc2 = UIViewController()
vc2.view.backgroundColor = .systemPurple
let tabBar2 = UITabBarItem(tabBarSystemItem: .favorites, tag: 1)
vc2.tabBarItem = tabBar2
tabBarController.viewControllers = [vc1, vc2]
  • Assign your initial view controller as the window’s root view controller and make it active:
window?.rootViewController = tabBarController
  • And the the bit I forgot at first. Remove all references in the app’s info.plist to the storyboard. There are two entries that need to be dealt with; Storyboard name and Main storyboard file base name. The former of these is buried deep within the Application Scene Manifest tree. I found them by searching for “main” and deleting all entries.

Run it, and with a bit of luck you should get an empty tab bar app appear!

The code in full:

3 thoughts on “XCode 11 – New Project Without a Storyboard”

  1. Spend several days trying to understand what is wrong and why my app throw the erooro at the start. I paying with coordinator pattern and disable initial checkmark for view controller. I move all the code to SceneDelegat and all works as expected. Thank you alot!

Leave a Reply