I 💖 Storyboards & Nibs

One of my favorite talks at @tryswiftconf (ok, every talk was my favorite!) was when @helenvholmes talked about how to get designers into code. One of the big things to do is very obvious – use Storyboards! Immediately, this comment was a bit controversial among developers.

Honestly, I don’t see the whole controversy. Does Interface Builder have a few issues? Sure! But in my experience, the benefits far outweigh the issues. And it’s not just about getting designers into the codebase. It’s about getting anyone into the codebase. It’s about making your big code base readable!

As a developer first introduced into another codebase, it’s so nice to go to the Storyboard, identify the View Controller I’m seeing on screen, and start working from there.

That said, Storyboards are a tool. And just like any tool, when used in the wrong way, it becomes useless and even worse, harmful. So I wanted to list a few tips on how to use Interface Builder effectively:

Multiple Storyboards

The biggest issue with Storyboards that I’ve seen is that developers start their project in Main.storyboard and start adding EVERYTHING in there! Soon, the storyboard becomes huge, a spiderweb that touches everything in the project. And as more developers are added to the project, no changes can be made because everything will conflict in a merge.

I think of Storyboards as pieces of code. Keep them small and isolated! I like to have a Storyboard for every part of my app that has it’s own single user-flow. For example, the sign-in / sign-up user flow can be completely isolated from the rest of the app. Or the Settings screen with all the settings options / flows. If my app has tabs at the bottom, each Tab would be it’s own Storyboard.

Sometimes I have Storyboards with only a two-screen isolated flow. But I’m ok with that. I know that in the future, it’ll be easy to add to it as the project grows.

Using this system, I haven’t had that many issues with merge conflicts. I can work on the Settings feature for example, while another developer works on fixing the Sign Up. Our stories are isolated and do not conflict. If we are working on the same user-flow within the same isolated Storyboard, we most likely need to collaborate anyway to make sure we’re not working on conflicting things.

Now with Storyboard References, it’s even easier to maintain multiple Storyboards.


I especially love Storyboards for laying out the flow of the application. It’s an easy way to see how each screen relates to each other, and what the options are for each screen. Again, this is a level of readability that is hard to replicate with one glance in code. That is the most powerful part of Storyboards. Putting every single view / design is not what Storyboards should be primarily used for.

Most of our apps have re-usable views and Table View Cells. If you add the same view in the same or different Storyboards, isolate that view into a Nib! Again, your Storyboard / Nib “code” should be re-usable and isolated if possible.

Since I like to re-use views as much as possible, sometimes my Storyboards look like this:

Storyboard Empty

I’m completely ok with keeping most of my views in Nibs (or code if it makes sense!). To me, an empty-looking storyboard like this is still useful for glancing and seeing the flow of the user story. I can easily click into each View Controller to find out more.

IBInspectable / IBDesignable

Another big issue I’ve had with Storyboards / Nibs is that I might need to make a small design tweak to my view that’s not possible to do in the Storyboard, so the the view in the Storyboard looks different than it does when I run the app.

Well, now with IBInspectables / IBDesignables, we can add those extra design fields to the storyboard. Oh, and we can see how that changes the look of the screen right there in the Storyboard / Nib!

Autolayout / Stack Views

Doing Autolayout is hard enough without having to try to do in code with no visuals. I love that Storyboards / Nibs tell me right away when I’m missing a constraint and I can fix it until there are no warning signs. Same goes for Stack Views – it’s nice to see the views click in place and adjust from there!


As an iOS developer, I really enjoy using Interface Builder and really don’t see why some developers are so against them. Of course if you use these tools in the wrong way, they will have consequences. But as long as you keep your IB files modular and isolated, just like any good piece of code, there are a lot of benefits to readability for everyone involved in the project.


Enjoy the article? Join over 14,500+ Swift developers and enthusiasts who get my weekly updates.

  • Joshua Kaden

    I like to have a custom initializer for my view controllers: to, for instance, inject a data manager or collection. But I haven’t found a way to use a custom initializer via a storyboard, which has been enough to make me steer clear of storyboards when I can. I was wondering if you have a solution for this problem?

    • Kiel Gillard

      Any particular reason you need a custom initialiser?

      • Joshua Kaden

        Mostly for dependency injection, like to pass in a data manager. I could inject via a public property, but then the property has to be a var (and public). The property that stores an init parameter can be a private let, which feels better to me.

        • I prefer to use the implicitly unwrapped var that gets assigned in init rather than mess with View Controller init lifecycle.

        • I agree. Also, you have to remember to set the var every time you want to use the view controller.

        • Curtis Duhn

          I look forward to using the implicitly unwrapped var trick when I migrate to Swift. For now, here’s the idiom I like to use for dependency injection with storyboards in Objective C:

          1. Each view controller has a public method starting with setDependencies like this:

          – (void)setDependenciesViewModel:(XYZViewModel *)viewModel delegate:(XYZViewControllerDelegate *)delegate
          self.viewModel = viewModel;
          self.delegate = delegate;

          2. Each view controller has a private method called -assertDependencies, which I call at the top of viewDidLoad.

          – (void)assertDependencies
          // injected dependencies
          self.viewModel &&
          // also a great way to remember those IBOutlet connections!
          self.titleLabel &&
          self.collectionView &&
          self.collectionView.datasource &&

          – (void)viewDidLoad
          [super viewDidLoad];
          [self assertDependencies];

          3. Now simply call setDependencies in prepareForSegue:

          – (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
          if ([segue.identifier isEqualToString:XYZSegue]) {
          XYZViewController *viewController = segue.destinationViewController;
          NSParameterAssert([viewController isKindOfClass:[XYZViewController class]]);
          [viewController setDependenciesViewModel:[self viewModelForSelectedThing] delegate:self];

          One of the things I like about this idiom is that all the dependencies of the class are bundled up in a single method signature, just like a good initializer. If you forget to inject a dependency, you find out about it at compile time.

      • Joshua Kaden

        That’s a nice solution; thank you! I’m still not totally sold, but thanks to you I now know what to do when I need to use a storyboard.

  • I completely agree, and actually just released a course on lynda.com this subject. Interface Builder is not without its own learning curve, and challenges at times. Yet I prefer to use IB over code for several reasons. I find it much easier to design visually. Doing so also benefits collaboration with clients, designers, and product managers. I as well as our designers design directly in storyboards (and use PaintCode to create UI elements, custom controls, etc.). Every line of code you don’t write is a line of code you don’t have to write…or test, or maintain; when Apple changes UI or AL APIs, storyboards will automatically be updated. Stack views make laying out UIs–even complex ones–much easier than using AL constraints. And as you mentioned, storyboard references making breaking up large storyboards into multiple ones easy, which addresses the issue of using storyboards on teams. The one issue that still remains is that just accessing a storyboard file marks it dirty for source control, so you have to remember to discard unintended changes before committing. We use a Trello board to keep track of who has what storyboards checked out. This is a small price to pay for all the advantages.

  • Apokrupto

    Well all the cool kids do their UI in code…

    Thankfully, I’m not cool and it’s been far too long since I was a kid. So, yeah, Storyboards all day please. If you want to do UI in code in your own projects, fine, but if you’re working in a team and want other devs to jump right in, then it’s unfair to present them with the higher learning curve compared to a quick look at the apps layout.

    I am, however having to ease back on my overuse of IBDesignable, it causes far too many Xcode crashes.

  • Nice article. I especially agree with out awesome @IBDesignable and @IBInspectable are for design.

  • First, thank you for writing this blog, I’m a designer learning swift and your posts are helping me wrap my head around some concepts and best practices.

    Could you write more about how you design separate independent views in Nibs for reuse? I can’t find anything detailing that online. What are the best practices for structuring and importing these views? And what’s the right way to pass data to those views?

  • Роман Волков

    Thanks for your point of view.
    I have a question about dividing common views across several navigation controllers.
    E.g., I have
    1. Navigation Controller -> List of items
    2. Navigation Controller -> Another view-> Another view -> List of items
    Tapping of each item leads to another flow of views and all of them should have the same navigation controller (like Navigation Controller -> View -> View -> List -> Details -> View and all of this items should be pushed into one Navigation Controller). Each Navigation Controller is an item in Sidebar menu.

    What is the best way to organise views files? Thanks

    • You could subclass UINavigationController and have it both instantiate the view controllers (using the UIStoryboard) and control the push/pop navigation. You would lose segues, but I consider segues to be lower on the list of reasons to use Storyboards.

      • Роман Волков

        thanks, I’ll try something like this