Tim Dietrich

Custom Software Developer

Home Services Portfolio Blog About Contact Newsletter

Swift: Developing iOS Apps With Multiple Storyboards

One of the challenges in developing complex iOS apps is that they often lead to large and unwieldy storyboards, with many scenes and segues. Working with this type of storyboard can be confusing, slow, and frustrating.

I recently worked on an app that provides multiple, related functions. It did not make sense to split this multi-purpose app into a series of smaller single-purpose apps. As development of the app progressed, the storyboard grew quickly. At one point it included more than 25 scenes.

So I decided to split that single storyboard up into multiple storyboards. While the process took time and effort, developing the remainder of the app became much easier. In addition, the code became more modular, making it possible to reuse not only the view controllers, but the storyboards as well.

In this post, I'll explain what's involved in developing iOS / Swift apps that use multiple storyboards. I'll show you how to create additional storyboards, and how setup navigation between them.

Creating A New Storyboard

To create a new storyboard, open your Xcode project and select File > New > File... Next, under the iOS file options, select User Interface, and select Storyboard. Click Next, and you'll be prompted for a name for the storyboard file and a location within your Xcode project.


When you create a new storyboard, it is empty. No default view controllers are placed on it. Therefore, you will need to manually add the first view controller. (If you're unsure of what type of view controller to add first, then I recommend starting with a Navigation Controller.)

Setup the view controller so that it is the "initial view controller" for the new storyboard. To do so, select the view controller, bring up the Attributes Inspector, and check the "Is Initial View Controller" option. You'll find it listed under the View Controller options.


To reference the view controller programmatically, you need to give it a Storyboard ID. Select the view controller, display the Identity Inspector, and then assign the name in the "Storyboard ID" field. (The field is located under the Identity options.)


Navigating To The New Storyboard

With the second storyboard setup, you can now add code to link to it. In my example, I simply added a button to a view controller on the first (or "main") storyboard. Then, in the view controller file, I added an IBAction for the button, so that when it is clicked, the second storyboard is displayed. Here's the code that's involved:


@IBAction func storyboard2ButtonAction(sender: AnyObject) {
	
	// [1] Create a new "Storyboard2" instance.
	let storyboard = UIStoryboard(name: "Storyboard2", bundle: nil)
	
	// [2] Create an instance of the storyboard's initial view controller.
	let controller = storyboard.instantiateViewControllerWithIdentifier("InitialController") as UIViewController
	
	// [3] Display the new view controller.
	presentViewController(controller, animated: true, completion: nil)
	
}

Let's take a look at that code. [1] We start by instantiating an instance of the second storyboard. [2] Next, we instantiate a view controller on that storyboard. We do so by calling the instantiateViewControllerWithIdentifier method of UIStoryboard class, and passing it the Storyboard ID that we assigned to the storyboard's initial view controller. [3] And finally, we actually display the view controller by calling UIKit's presentViewController function.

Returning to the Main Storyboard

When you're designing an app with multiple storyboards, you'll often want to give users a way to return to the storyboard that they navigated from. What you do not want to do is instantiate a second instance of the original storyboard. That will quickly turn into a nightmare, and your app will very likely crash.

Instead, you'll want to dismiss the second storyboard, so that iOS naturally falls back to the original storyboard. To do so, you'll need add a button that kicks off the dismissal process. In my case, I added a Bar Button Item to the navigation bar of the view controller on the secondary storyboard. Then it was just a simple matter of adding an IBAction for that button to the view controller. Here's what the code looks like:


@IBAction func doneButton(sender: AnyObject) {
	dismissViewControllerAnimated(true, completion: nil)
}

Sample Xcode Project

I've created a very simple Xcode project that demonstrates the multi-storyboard approach. Feel free to download it here.

A few screenshots of the sample app are included below.