The anatomy of an iOS storyboard

Chris Mash
6 min readSep 2, 2019

--

A storyboard, in terms of iOS app development, is an XML file which is used to visually layout an app’s UI. The XML format is very similar to that of Nib files, the ‘predecessor’ of storyboards (but still very much in use for certain use cases).

In general an iOS developer doesn’t need to understand anything about this XML format. That is… until they’re working in a team, with source control, and there’s a merge conflict in a one of these files… At which point you find you have no clue what any of the XML means and therefore no clue how to resolve the conflicts!

In Xcode 10.2 a storyboard with one view controller, which has one button in it, will look a little something like this:

Now that you’ve taken all that in, let’s take a closer look at the main elements.

<document>

The root element is <document>, which defines various metadata and settings for the storyboard:

The initialViewController attribute is of interest. It’s the identifier of the view controller which the storyboard will start from. Another attribute you might often see changing/conflicting is toolsVersion, this is the version of Xcode the file was opened with last. So you might get conflicts if your team aren’t all on the same version of Xcode.

<device>

Next comes the <device> element, which defines which iOS device the storyboard will be previewed with.

This could be an iPad or iPhone of various sizes and could be portrait or landscape. You’ll see changes/conflicts here if your team aren’t all using the same preview device.

<dependencies>

After that we’ve got the <dependencies> element, which has some similar details to those found in the <document> element. These are a list of things that can help Xcode determine whether it can understand the XML file and might change as you upgrade to a new version of Xcode.

Again, you could get changes/conflicts here if you team aren’t all on the same version of Xcode.

<scenes>

Now comes the <scenes> element, which is where all the view controllers will be listed, each within their own <scene> element.

But what’s a ‘scene’? They’ve been there in storyboards since they were introduced in iOS 5 (I assume), so they’re not related to the new UISceneSession functionality in iOS 13 (for multi-window support in iPad apps).

You might not even be aware of this, but in a storyboard, a view controller can have views associated with it that aren’t in its view hierarchy.

You can drag a view onto the bar above the view controller and then it will be listed within the <objects> element of the scene and appear tethered above the view controller.

I’ve very rarely used this myself, but it could be useful for overlays or popups that you’ll show on your view controller at some point but don’t want the view in the hierarchy all the time. You can put the view in an @IBOutlet on your view controller so that you can add it as a subview at the appropriate moment (don’t use a weak @IBOutlet though as nothing else will have a reference to it so it won’t stay around for long!).

The last element in the <scene> above is a <point> element, which defines where on the storyboard that scene is displayed, so that changes if you drag the view controller to a new position in the storyboard (and could cause a conflict if someone else does something similar at the same time).

<viewController>

Within a scene’s <objects> element we can have a <viewController> element. As you can probably guess, this defines all the details for the view controller and its view hierarchy, so can get quite big!

Within the <viewController> element we have a <view> element, which obviously defines all the details of the view controller’s view. The <view> element will have a <rect> element defining its frame so Xcode knows its size and placement for displaying it in the storyboard. There’s also a <color> element which defines the background colour of the view.

Then we’ve got the <subviews> element. You’re probably way ahead of me on this one. The <subviews> element defines all the details about the subviews of a view, which can each have their own <subviews> element (and on and on).

<button>

Seeing as my example storyboard has a button in it, let’s have a look at that.

A lot of the elements are things we’ve seen before: <rect>, <color> etc. The <constraints> element was in the previous image but I didn’t show any details there. In this image

The <connections> element is brand new. This element is where segues between screens are defined. My storyboard has a segue being triggered from the button click through to another screen which I sneakily edited out of the XML that I’ve shown you.

In the image above you can see what details a segue has. As you might imagine it has a destination attribute, which is the identifier of the view controller it leads to, an identifier of its own and its kind (or type).

You can also define segues that aren’t triggered automatically like this one is, but instead just link from view controller to view controller. These segues would instead be listed in a <connections> element within the <viewController> element.

<inferredMetricsTieBreakers>

Eh? This one wasn’t in the example XML… But here’s what it looks like

In a simple storyboard you won’t see that oddly named element as it only comes into play when you have multiple segues going to the same screen.

This element lives right at the bottom of the XML and will list any segue identifiers that are used to decide in which way a view controller should display itself in the storyboard. For example, if the screen can be segued to from a screen that’s in a navigation controller and from another screen that’s not in a navigation controller (and the view controller being segued to has it’s ‘top bar’ set to ‘inferred’), then Xcode needs to know whether to show a navigation bar on that view controller or not. By clicking on each of the segues leading into a view controller you can change how it’s displayed to you (e.g. the navigation bar would appear/disappear in this example) and that will change what’s listed in the <inferredMetricsTieBreakers> element (which could be multiple <segue> elements as your app becomes more complex).

<andTheRest>

There’s more to the storyboard XML format than that but hopefully this brief introduction will set you on the right path for understanding what all that XML means and help you merge conflicts with more confidence!

--

--

Chris Mash

iOS developer since 2012, previously console games developer at Sony and Activision. Twitter: @CJMash