Copy Xib To Storyboard

This post describes how you can migrate (or copy) a Xib file into a Storyboard and retain all the components and constraints.

In a previous post, I demonstrated a strategy and demo app to migrate an Objective-C app into Swift, with minimal disruption and rewriting. Today I’ll go one step further and cover the case where you have Xib files in an Objective-C or Swift app, and want to move them into Storyboards. You might wish to take this approach if you want to take advantage of segues and unwind segues.

The process of doing the copy is actually simple, but I’ll describe the complete Xib migration in this post by illustrating it clearly with a demo app, so be forewarned that this post is longer than it could potentially be 🙂

The demo app is a simple UINavigationController based app with a main UIViewController in the default Storyboard, and two buttons, one to go to the initial Xib MyViewController, and the other to go to the same controller but via its soon to be defined Storyboard definition. With the MyViewController currently in its own Xib, the storyboard has only the Home Scene and Navigation Controller Scene as you can see below.

Here is the MyViewController.xib and its contents.

In this demo, I’ve purposely used more constraints than necessary, instead of making full use of stack views to minimize the number of constraints. This is to help illustrate moving components and constraints to a Storyboard.

Now we want to copy the Xib definition into the Storyboard. Let’s drag a new UIViewController into the Document Outline under the Navigation Controller Scene.

Now comes the main point I’m showing in this short post. Select only the root View from the Xib file contents, and then Cmd-C or Edit > Copy. You don’t select the whole View hierarchy or all the components and constraints under the View.

 

Now go inside the new View Controller and select the root View. This is the part that might seem counter intuitive because you’ve just copied what was under a Files Owner, so you might think to select the View Controller and copy the View into it. This won’t work.

You need to select the View you wish to replace in the new View Controller Scene, and then paste the contents you copied. xCode will now happily add your original root View as the root View of the new View Controller. You’ll now see everything, including the constraints, all copied over.

There are three quick steps left. First, we need to set the Custom Class in the new View Controller (not the View) to be the same MyViewController, since we are reusing that controller class.

Then we need to make the connections from the new View Controller Scene to the IBOutlets in the MyViewController class. In the demo app, only the Label had an IBOutlet so we can just Ctrl-Drag from the Label to the existing IBOutlet in the MyViewController.

Finally, we will add a segue to open the new My View Controller Scene from the Storyboard instead of manually creating and pushing it onto the navigation stack as was done with the Xib version.

After that step, the app can be run and the second button will now open the new View Controller scene from the Storyboard, with the user interface looking identical when triggered from both buttons.

If this was a real project, you could now delete the original Xib file.

I don’t recall personally having seen this process documented by Apple, but it has worked for me in a number of cases.

If you want to check out the demo app and repeat the steps yourself, you can download the project from GitHub. Just delete the My View Controller Scene, then walk through the process, starting with the copying of the original View.

Leave a Comment: