35 comments

[ 2.3 ms ] story [ 96.6 ms ] thread
When I switched from web to iOS development, I did 99% of design programmatically because it is what I was used to (CSS). The only things that I used interface builder was for segues. The frames of each element would be dependent on one another, so if I were to change the frame values of one element, it would adjust everything else accordingly, which was perfect.

However, doing things programmatically takes a long time, so much time wasted trying to align things in your head then implementing it. After talking to a friend who did iOS development for a long time, he convinced me to switch to interface builder. I couldn't be any happier. Firstly, all the elements are available visually, this is a big help to me and anyone else that looks at the project. Secondly, handling size and alignment in interface builder will be daunting initially, but once you get the hang out of it, it becomes extremely easy. The biggest advantage is the amount of time you save from not having to write code.

The author points out the negatives to interface builder, which is pretty important. Maybe iOS developers should start diving into the XML like Android developers.

I've done android development as well as iOS development. The big difference is that the xml spat out by the android tools is readable and easily hand editable as opposed to the xml produced by interface builder.

At the start of the article I make be point that interface builder is great for solo developers or small dedicated IOS teams. My main critique of interface builder is its use in a larger cross functional team setting. That doesn't sound like your use case.

Re manual view layout: Have you looked at any third party libraries like masonry, snapkit or componentkit? When I worked at Facebook we used ComponentKit and it was a much better experience than manually calculating the positions of views.

The XML spit out by interface builder these days is pretty readable too. Have you looked at it in the past few years?
Yep, it's still pretty unreadable in my opinion.
IB XML is nothing like Android XML - they're world apart in readability. Trying to edit the IB XML directly is almost impossible -- I've tried.

Honestly the best part of new tools like React Native is how it let's you get away from IB without the huge hassle of trying to declare your whole interface directly in objc/swift.

It might be interesting to have an interface builder that output code, instead of XML.
Betteridge's law definitely applies here.

https://github.com/PureLayout/PureLayout

PureLayout is a fantastic library for layout on iOS. There's no weird operator overloading, or semantically odd DSLs. It just feels like Cocoa. It's very much "the missing autolayout API".

Everything just returns layout constraints, so if you need to alter the priority or activeness, just use whatever method you choose (i.e. ReactiveCocoa). Unlike IB, it's type safe, and fully annotated for Swift.

Never seen this library before but it looks very cool. Could be a great middle ground between laying out views with visual format and storyboards.
I've never really grasped how to use Interface Builder, I've tried a few times and its just never worked right the first time or felt like the right way to do it. So I've always just taken the approach to pragmatically build my views.

The only issue I've ever had doing it this way was the new Launch Screen to support the newer iPhones, luckily centring a few images isn't too hard to do in Interface Builder. That and writing out constraints can be quite verbose in code.

writing out constraints can be quite verbose in code

Out of the box, yes but Masonry/SnapKit[1] make this almost a pleasure.

[1] https://github.com/SnapKit

Apple are pushing storyboards a lot but that's all about making the learning curve less steep for entry-level developers. Doing UI programmatically is going to be the way to write any reusable piece of code, unless Apple change Interface Builder to generate ObjC/Swift classes rather than XML.
Interface Builder has successfully produced every UI in the system since 1988, you know. NSCoding, nibs and IB are older than most systems with UI declarations in code.
Choose whatever works for you. Interface Builder can save you so much time building some of the smaller aspects of your app (help/about screens) etc. that it's foolish in my opinion to just "do away" with IB on principle.

Sure, if you have 1 storyboard for your entire app, and 9 people are working on it, you will have collisions. 9 people on an iOS project is bound to have merge conflicts in code too, unless it's coordinated.

Xcode 7's storyboard references should help avoid some conflicts here, as it breaks up a single, conflict-magnet file into several. Hell, you can organize them like XIB files before Apple started pushing the 1 storyboard "simple" approach to ease the learning curve.

Side note: The title of this post should have been "Reasons we are switching away from Interface Builder", as it doesn't actually answer the question. But then it wouldn't be interesting enough to click on.

Even with 1 storyboard, as long as you don't commit completely unrelated changes, you can still have 9 people working on it just as easily as you can if you split it up into one storyboard per view controller. All this requires is that people actually look at the diff they're committing and omit changes to unrelated view controllers (most graphical commit tools will let you pick the lines to commit).
"Choose whatever works for you. Interface Builder can save you so much time building some of the smaller aspects of your app (help/about screens) etc. that it's foolish in my opinion to just "do away" with IB on principle."

To be fair I never said that we were doing away with interface builder on principle. I also said that interface builder was great for smaller teams.

My main critique of interface builder is that it's not a great fit for larger cross functional teams because it makes code review difficult and it's hard to resolve merge conflicts.

These are not problems that the vast majority of app developers face. These are problems that happen on larger cross functional teams.

Their is a reason that neither Facebook, Airbnb, Pinterest nor uber use interface builder.

I love the immediate feedback and the ease with which you can layout views in the IB, but it can be a nightmare for teams. Any time a storyboard is touched, the file is updated in some way. The diffs are large and unintuitive, and merging is tedious. If Apple wants to continue to push the IB, they need to make it more compatible with teams and source control.
Such misinformation here. First, the merges usually happen automagically. The automatically added diffs, if any, are usually tiny and targeted.

If it's a nightmare for a particular team, that team just needs to learn how to use IB. One person (or one pair if you're doing that) should work on a scene at a time. And it's really easy to have storyboards broken up into multiple storyboards, which makes most of these red herring issues go away anyway.

I think people get fooled by the fact that the UI is visual. There it is, in front of you, so you think you should be able to add multiple interdependent constraints while another person with their own copy of the same file is adding conflicting interdependent constraints to the same scene. Note, I didn't say "independent" I said "interdependent." That will never work, ever, in any system. It won't even work if you do things programmatically, with different people changing interdependent constraints at the same time and then expecting them all to merge and work without pain. It's not even really an IB issue; you just see it in IB because the visual UI makes you think it should just work like magic.

I wonder how hard it would be to build a nice diff tool for IB files. If you could (semi) visually view the changes in a meaningful way, maybe a lot of this would be helped. Conflicts would still be hard to merge, but maybe something could be done about that as well.
Here's an alternative that I've worked on:

https://neonto.com

Neonto Studio generates native iOS and Android code from visual layouts. You get full Xcode / Android Studio project files, ready to run.

It helps avoid IB-style merge conflicts because the visual layout is kept entirely separate from the Xcode project. Changes made by the designer won't mess with the main repo. When it's time to bring them together, you export from Neonto Studio and merge the generated classes with any changes in the mainline Xcode project. Since the Neonto-originated UI is code, git branches + git merge works well for this.

We've moved away from Storyboards, mostly for author reasoning alone. Usually only have 2-3 people on a project at once, but merge collisions on Storyboards are a mess. Really could use some improvement by Apple. Never mind that working on complex storyboards is a mess, especially if you need to work on a laptop screen for some reason.

A project with many single XIBs isn't the best, but I helps with conflicts, and probably better than writing all UI in code. The biggest issue with coding out UI is that our designer is always going to have trouble with that complexity, and we need him to jump in and make changes.

Are you aware that you can split different scenes into different storyboards? That helps a lot with the issues you mention.
Fortunately, the problem of having to share a single Storyboard file has been eliminated in the last month's Xcode 7 / iOS 9 release, with the addition of Storyboard References.

Now, developers have a first-class solution to connecting separate Storyboards files, in a Storyboard. This gives you the ability to scale the number of Storyboard files you have in your project. If you're having too many merge conflicts on the same Storyboard file, you can break up your Storyboards into more files.

That said, I'll concede and say that the single biggest problem with Storyboards is that it doesn't work well with text-based CVS, namely Git. Sure, fine.

...but, Storyboards offer a few HUGE advantages (all of which can't be replicated by anything else):

-Storyboards are the single best way to document your UI and application flow. If you do all of your UI implementation in code, it makes it near impossible to determine these things without following a 'run it and check it' approach. In Storyboards, you can visually see UI designs in a GUI environment, as GUIs should be displayed.

-Storyboards mean less code. You're not maintaining constraint objects and configuration details. All of that is contained in the Storyboards. In my all-Storyboards projects, I'd say the codebase is 15-20% smaller.

-Storyboards allow for quicker iteration cycles. You can align a button by changing a slider value, as opposed to tweaking a constant and continuously recompiling + running the actual app.

-Storyboards allow for more effective UI design. You can see your UI, as you design it. This, opposed to trying to take a design mock and blindly replicating it in code.

So, my perspective on Storyboards is that, if you're willing to sacrifice a certain amount of 'code review blindness', you stand to gain far more in the day-to-day and long-run of your project.

I'd add there's a huge advantage to using storyboards (especially with storyboard references) if you have a savvy UI Designer on the team who is comfortable using Xcode.

Under ideal circumstances, storyboards can allow non-iOS engineers to make substantial contributions to the UI and rapidly prototype new things.

> the single biggest problem with Storyboards is that it doesn't work well with text-based CVS, namely Git

The way LabVIEW solved this problem, being a proprietary and graphical language, was the inclusion of LVMerge and LVDiff tools. You could configure Git to use these to merge or diff the files when needed.

Hopefully Apple gets this fixed soon.

Edit: someone tried to make something like this, although I've never had the pleasure of trying it out. Perhaps someone could try it and tell us how it went with his or her project: https://github.com/marcinolawski/StoryboardMerge

The tipping point for IB came with Auto-Layout. Realtime feedback when setting up constraints makes a huge difference.

The risk of merge conflicts, can be alleviated by breaking down your massive storyboard into smaller ones that deal with each flow. If that doesn't setup appropriate boundaries for your teams, break them down into one storyboard per view controller. If that isn't modular enough, use XIBs to at least layout views.

The merge conflict argument is overrated. The vast majority of apps don't need more than a few developers working on user facing code. You're building an iPhone app, not an operating system.

As far as I can see the only way to easily review changes made using Interface Builder, barring getting really good a reading raw XIB files, is to manually checkout and review each pull request. Doing this is of course incredibly tedious, time consuming and not something I suspect most people have the discipline to do consistently.

In Gerrit, code reviews include a one-liner you can copy and past to checkout the branch up for review. Regardless of the IB debate, if your code review tool doesn't do this, invest in tooling to make checkouts as frictionless.

Why has the Xcode team not solved this problem. It's been a consistent complaint since the interface builder was released. Xcode has git support out of the box. I have to think a visual differ would've been along by now.
It's not the tool, it's bad developer practices. See my other comment on multiple people editing the same interdependent constraints. Never a good idea, even in obj-c or swift code.

Complaints happen; it doesn't mean the complainers are using the tool correctly.

But it does raise a possibility: Maybe the Xcode team could make it easier for a developer to do something along the lines of checking out a single scene to work on, at least putting other developers on notice that they will be risking merge issues if they work on the same scene.

Normally issues can be avoided by just coordinating work such that people aren't editing the same code at the same time. This goes for XIB or storyboard "code" too. Yes maybe Xcode could do something, but that something would probably address developer behavior more than it would address merging per se.

"t's not the tool, it's bad developer practices. See my other comment on multiple people editing the same interdependent constraints. Never a good idea, even in obj-c or swift code."

That doesn't address the fact that properly reviewing changes made by others to xib files generated by Xcode pretty much requires you to check out those changes and review them in interface builder. That's a lot of friction for larger teams who don't just do iOS development.

As I said in my article I don't think interface builder is terrible or anything, I just think it's a poor fit for larger teams doing cross functional development.

You seem pretty confident in your argument that developers are just complaining while using the tool wrong. It makes me think that your experiences in UI development on large teams is limited.

There is a reason why you hear this constant complaint, and the reason is because IB is really horrible in this regard. Behind the scenes it is generating unnecessarily verbose xml that is not developer friendly at all. This is unacceptable. Even Microsoft did a much better job when generating XAML from Expression Blend, and this was half a decade ago.

I'm not sure if you've ever used react-native, but imagine if IB generated ode that looked like a react component. Not a single soul would be complaining because these problems wouldn't exist.

I wonder that nobody mentioned view definition reusability which is totally lacking with storyboard UIs and one of the primary reasons why we also moved from using storyboards to doing everything in code with ComponentKit.

Just think about a table view cell. There is no clean way if you want to use the same custom cell layout in two different view controllers. Your only options are copy/paste or hacking around that with XIBs and additional code. Guess what, having half of your UI in code and half of it in a storyboard doesn't make maintenance easier in the long run.

This, and other problems, is perfectly solved by ComponentKit.