Storyboards vs. Xibs - iOS9 - ios

I know this is a question that has been asked quite a bit, but it's iOS 9 and I still don't have a clear idea about what to do. For starters, here is what I seem to be surmising from all the data available:
Storyboards let you create segues. [I've never been a big fan of this answer because segues are often the least harrowing part of creating the UI layout for me.]
Xibs can let you create multiple top-level views. (Storyboards vs. the old XIB way) [I don't think I've ever used this much, though it seems rather helpful.]
Storyboards - Creating UITableViewCells is easier. [In my opinion, it's cleaner to create xibs for the cells and just invoke them in cellForRowAtIndexPath].
Storyboards can turn into one giant ultramassive file that is hard to edit. [I've seen this happen in practice and it is a big drawback, but at the same time...]
Storyboards let you arrange all your Views in one place with the layout shown as well. [This seems to be a big help for me. But then, over the years I've found doing this in code much easier. Which brings me to my final question.]
What is the performance aspect of both of these two things. My app is essentially the following :
A top level hierarchy of interconnected view controllers, not more than 5.
A large number of disparate, independent view controllers that range from Scroll Views to TableViews to static Imageviews.
Autolayout, size classes, the works.
For each of these view controllers, what is the performance of creating a storyboard for each of them vs. creating a xib for each of them. More importantly, what would be a good way to lay out an app like the one I've mentioned.

You definitely want to use storyboards for laying out view controllers - simply because you get access to topLayoutGuide and bottomLayoutGuide which the XIB editor won't give you.
For other views, it's a matter of preference. I tend to use XIBs for table view cells simply because I tend to reuse them on different screens and prefer to have them in their own files.
I would actually advise against manually writing view code where possible simply because it's much harder to read and work out how views are laid out, especially for developers who didn't write the code originally! For simple, dynamically sized things this can be fine, but if you're trying to lay out view controllers with different constraints depending on the size class it's going to end up a bit of a mess.
Yes, it's a pain to deal with merge conflicts of these files, but with iOS 9 you can split up view controllers into different storyboards a lot more easily using view controller references. Personally I find the inconvenience of merging storyboards/XIBs the lesser evil of having to write everything in code.

It sounds like a Storyboard is the right thing for your current project. However, my experience has been that Xibs and Storyboards are problematic in the real world, for these reasons:
extremely idiosyncratic from developer to developer, so it is tricky to build good storyboards as a team
black boxes, so they require a tremendous amount of knowledge to master (unbelievable amount of hidden behavior). Only the most superficial semantics are covered in the documentation.
internationalization is made much harder by being split up, especially if you have internationalized messages not contained in the Storyboard/Xib.
backwards compatibility breaks annually / deprecation guaranteed over time. This is especially difficult if you try to maintain compatibility with older devices.
As soon as more than two devs started touching our code we rewrote everything to avoid Storyboards and Xibs altogether, and we became much more productive.
If you have to deal with any of those real world situations, I heartily recommend programmatically creating all of your views. There is even an app that makes this easier (and is way more scalable). I have no relationship with this company or product, but it is hands down a better solution.
http://www.paintcodeapp.com/

Related

How to handle alternate views within a scene

I am making modifications to an existing iPad application, and I'm having a hard time dealing with really messy scenes in storyboards. Almost every scene in the app consists of multiple views laid one on top of the other, each containing a different set of controls. Depending on the situation or data coming into the scene, some views are hidden, and others are shown.
It takes a LOT of time to decipher such scenes, and even when I figure out what changes I need to make it's terribly difficult to make those changes, and easy to screw up other things.
As an example, the following scene has 3 views that could appear (Start View, End View, Drawer History), depending on the situation, and they are all laid out on top of each other...
This seems like a terrible way to handle this, and I'm having a hard time believing this is standard practice, but I'm not finding much in the way of alternatives. I find very little in the way of questions where people are dealing with this problem, and the tutorials on how to design user interfaces seem to be too simplistic and never deal with scenes that are complex enough to run into this problem.
Unfortunately, this app is my primary introduction to doing user interfaces in iOS, so it has apparently become the default solution in my head. I've tried many tutorials, but they take a long time and don't seem to ever get to a situation that needs such a technique to solve it.
I would hope there would be a solution where each alternate view in the scene could be laid out on its own, and be made to appear within a placeholder view as needed.
What would be a more enlightened / more manageable approach?
That's what you'll get with Storyboards/Nibs/Xibs. I'm not saying coding your UI is better than using interface builder, but it is, at least for me. I believe, as far as I know, there's no other way to handle such multiple layers of views in one view controller in interface builder. I actually used to use interface builder before and that's how I add multiple layers of controls too. Sometimes some views are initially made hidden, but that would probably confused me or the other developer looking at the layout. Sometimes I extend the viewcontroller height to know that there's a view container with a constraint a thousand constant or a negative thousand constant to make it hidden and ready to animate when it's needed to be shown.
There are ways to somehow improve and organize your Storyboards. You can separate modules into different storyboard files; you can use references; avoid segues; and whatnot. It's still an individual or team's preferences.
Some ref:
https://cocoacasts.com/organizing-storyboards-with-storyboard-references
https://medium.com/#stasost/xcode-a-better-way-to-deal-with-storyboards-8b6a8b504c06
EDIT:
I'm thinking you could also layout separate view containers into a separate xibs, and then call them or layout them when needed. But that would add more files to your project.

Storyboard in Xcode

I've been working with Xcode for a while, and what I'm doing works, but I can't image that it is the best way to do it. When I want to transition between scenes in Xcode, I create a segue between UIViewControllers in the main storyboard. This is a picture of a storyboard in one of my apps.
By looking at the picture, you can probably understand why I'm curious about whether or not what I'm doing is bad practice. What should I be doing to transition between scenes, or what do most people do to transition between scenes? Thanks for the help!
This is not easy to answer, but I will give you some context:
Storyboards can be a nice visual way to remove push/present code from the view controllers and make it clear what is happening (vs code).
Having UIViewControllers handle navigation is not considered best practices (at least in many larger projects/enterprises). This is why patterns like VIPER (among other reasons, and yes VIPER can be overkill).
In your case the relationship is not clear, many things also go back and forth. Now it might be possible you can lay them out better, and perhaps the containment or relationships can be tweaked.
Here's some advice I can give. Try to make view controllers as dumb as possible about opening other view controllers, both the what and how - they ideally should just indicate to some controller/mediator/manager they wish to "do" something. It makes maintenance and refactoring a lot easier, especially adding a new feature later that might change how navigation works, such as adding on boarding into the app.
Long story short, storyboards are not bad, however many enterprise and large projects do not use them both due to the difficulty in version control with multiple developers (using shallow storyboards with NIBs can mitigate this, you do lose some of the Segue), and because you can tend to grow overly complex view controllers. Its great for personal, smaller apps... as complexity grows, value proposition becomes thinner.

Use storyboard or xib for single view controller?

I have to implement the layout of a single screen, which is not connected to the overall app flow, and I was wondering if it makes sense to use a Storyboard.
Storyboards make sense for flow/navigation (multiple controller), have some convenient features like, iirc prototype cells which are not available in xib. And it also makes sense if I think maybe later the screen may become a "story" (more view controllers). But none of this advantages are useful for my particular case.
I was thinking anyways in using Storyboard, as it seems to be a bit more flexible than xib generally, but is there any disadvantage? Maybe performance penalty or such? Is there a preferred way to setup single view controller?
Go ahead..take the advantages of using storyboard. There is no disadvantages or performance issues particular to storyboards when compared to xib files. Its all about your convenience. As you said the single view controller may become a story in future, then the storyboard would be a right decision. And when to use xib? thats upto you, one ideal situation where i will choose xib is, if i have an independent controller that i want to share with other project also then i would choose xib.
The performance penalty would only bother under the circumstance which too many controllers (more than 10) with segues were squeezed in one Storyboard. Everything would be totally fine before that.
And if you have more than two people are trying to edit same storyboard file than you have to resolve conflict, which will be more tedious job.
Storyboard benefits:
a. easy demo purpose and fast implementation.
b. small team like two person.
c. Storyboard is providing complete view and navigation model.
XIB benefits:
a. You can modularize your code.
b. More people can work on different-different controller without affecting your xib or code.

Show/Hide UI elements in a storyboard depending on the target

I have read a lot about creating a lite and a paid version with Xcode and in my app I am using multiple targets and preprocessor macros as described in this Stackoverflow post. However, I don't know how to handle different targets with a Storyboard.
For example, in my storyboard I have a table view controller with static cells. In the paid version it has four cells, in the lite version has one extra cell whereas the rest of the storyboard remains unchanged. Is there a way to achieve that kind of behavior?
(Creating a new storyboard for the lite version (or duplicating it) is not an option for me as I have dozens of view controllers and 98% of the views and UI elements are identical in both versions. It would make the project difficult to maintain.)
For example, in my storyboard I have a table view controller with static cells. In the paid version it has four cells, in the lite version has one extra cell whereas the rest of the storyboard remains unchanged. Is there a way to achieve that kind of behavior?
If you hadn't boxed yourself in by using a static table, this problem wouldn't have arisen in the first place; you'd be configuring the table in code, which can be conditional — end of issue.
As things stand, you'll need two different scenes in the storyboard, one for the paid version, the other for the lite version. Then:
If this scene is reached by a segue, you'll need two different segues that reach this scene, and you'll decide in code which one to trigger (and trigger it in code, not automatically).
If this scene is the initial view controller, you'll need to instantiate it initially in code rather than letting UIApplicationMain do this for you. Or, in that case, use two different storyboards for just this one scene, and then segue to another storyboard.
(And do keep in mind that multiple storyboards are a great way to organize your scenes in any case. I don't necessarily mean multiple alternative storyboards; multiple sequential storyboards can keep your storyboard from becoming overly complex. It sounds to me from your question as if all you need to do is understand how storyboards work - they are not magic, you know - and be more nimble in your use of them. Your entire deer-in-the-headlights fear of duplicating your storyboard - "I have dozens of view controllers" - suggests you've already gone way too far down the wrong road. Programming is like solving a Rubik's Cube: if you're in the middle of it and your response to someone trying to change something is "don't touch it!", you're doing it wrong.)

How does instantiating view controllers inside Xib files lead to code that is difficult to comprehend and debug?

In the introduction to iOS Programming: the Big Nerd Ranch Guide, the authors say that they always create view controllers programmatically, and that instantiating view controllers in Xib files leads to projects that are difficult to comprehend and debug.
What, specifically, makes this problematic? And which difficulties would you encounter?
Are there any specific examples, and how does creating the view controllers in code avoid these problems?
The quote is at Introduction > Style:
We will always create view controllers programmatically. Some
programmers will instantiate view controllers inside XIB file. We've
found this practice leads to projects that are difficult to comprehend
and debug.
They talk about instantiation. If you have two view controllers A,B, you can alloc/init B in A's implementation, or you can drop a reference to B in A's XIB. In both cases, B may be defined in a XIB or not (the Big Ranch book advises to use XIBs for complex view controllers btw).
Anyway, here is the difference:
CitySelectionVC *citySel = [[[CitySelectionVC alloc] initWithCities:self.cities] autorelease];
[self.navigationController pushViewController:citySel animated:TRUE];
vs
citySel.cities = self.cities;
[self.navigationController pushViewController:citySel animated:TRUE];
First case is a explicit instantiation in code. It tells me:
The VC is created now.
It needs the cities to work.
The code in the second block references an outlet instantiated in the XIB. It tells me:
A VC was instantiated at unknown time, with unknown requirements.
I'm passing the cities.
I favor the first style because it is more explicit, and gives me control of the lifespan of the object.
In iOS 5 you can use Storyboards to create transitions and pass information between controllers. See Session 309 of WWDC2011.
For completeness, here is the answer I received from Joe Conway (one of the book's authors) in the Big Nerd Ranch forum:
"When a low memory warning occurs, a view controller's view is trashed
to free up memory. When that view controller's view needs to go back
on the screen, it reloads its XIB file.
If there are controller objects (or really, any non-view objects) in a
XIB file, those also get recreated. Not knowing this can put your
application into an inconsistent state, because a controller that may
have held state (or held references to model objects that held state)
will be destroyed.
It could be argued that everyone should know this and take the
appropriate action to work around this. However, there are a few
problems with that argument: not everyone knows this and even if they
do know this, they are forced to open up XIB files to see the
controller hierarchy AND read through code. This makes things
difficult to maintain."
To my mind, this is less of a black-and-white, right-or-wrong situation, and more a case of personal preference. It's an old debate, as well - the "real programmers do it in code" argument has been around since mainframe days.
Possible advantages of building view controllers in code:
all the aspects of the interface are in one place, so you can figure out exactly what's going on by reading through one file.
it's arguably less complex to create the view, if you regard dragging-and-dropping in a UI builder as complex.
getting fine-grained pixel-perfect control over the UI can be painful in Interface Builder, especially if you're used to the level of layer and layout control from tools like Photoshop.
The counter view:
unless you're experienced or just that way inclined, getting a sense of how a visual interface looks and feels is very difficult from code.
working with end-users and designers on interfaces that are built in code is damn-near impossible.
sometimes it's just quicker to drag and slap controls and nudge them around until it's right.
Ultimately, it's a case of what works for you. I tend to do it both ways, depending on how complex the interface is, how quickly it needs to go together, and (frankly) the mood I'm in at the time...
This is kind of a philosophical question. It's hard for me to imaging getting the look and layout correct if it's all in code. On the other hand, using .xib files means that you have no single place to look to make sure all your outlets are actually hooked up.
Localization is IMO going to be much easier with .xib files, too — you can certainly do this with code, but when buttons change size it can be tricky.
It's very true that:"real programmers do it in code" but I do not see the problems while debugging until or unless you are not focusing on UI issue while debugging. It means to fix the UI issue you have to fix it through the IB and that issue you should not look into while debugging.
The biggest problem that developers face while doing UI through XIB is developing it in team and putting it in SVN. If you get any conflict and you are required to merge both the code, you have to play through the XML. Sometimes it becomes very tough to resolve the conflict in XIB manually. If you do it by coding you can easily make it done (because you know which line is causing what problem, and what to keep and what to remove).
I hope this will help you to decide on what should you keep in XIB and what you need to do by coding.
Apart from (as others have already pointed out) being a false dichotomy, I find the argument misleading:
While it’s true that you now have two places to look for where things may come from, when you are instantiating view controllers in XIBs, as soon as you need two configurations of the same view controller, you can only lose when you’re heading down the “code only” route.
In my personal experience, most of the code-bloat in the projects I saw or worked on came from a reluctance of separating configuration from functionality, i.e. forcibly “doing it in code” instead of “load a XIB with the configuration”.
In the worst projects, dozens of classes could have been avoided easily by simply treating configuration as data — and leading to better, more robust code because it would have been exercised more thoroughly.
So in my opinion, using XIBs even to instantiate other view controllers does not only not deteriorate the maintainability of a code-base, but can help a lot in actually improving it.
There is one single caveat to using XIBs:
You have to talk to each other — there are a few conventions you have to establish within your team, and you have to talk about who puts (or is planing to put) what exactly where and why.
Establishing conventions and talking about architecture, however, are the things you should be doing regardless of project or even programming language if you don’t want to end up with a huge maintenance nightmare…
A few tips for working with XIBs:
When writing view controllers, be liberal with asserts — if you have a precondition that something is there, put an NS(Parameter)Assert in your viewDidLoad and make sure the exception breakpoint is active, that way you’ll find missing connections easily (including those from code!).
Give objects meaningful labels, as the auto-generated names can become unhelpful quickly — when your view hierarchy grows in complexity, you won’t see much in your outline when you have a “View” in a “View”-with-seven-siblings-three-levels-deep-in-another-view or have ten UILabels that will be filled with data dynamically.
Set the editor to perform live autoresizing “Editor > Canvas > Live Autoresizing” most of the time. Only disable it, when you don’t explicitly need it.

Resources