Designing the iPhone interface in a nib or in code?

I was once very strongly against using Interface Builder in my own projects. This was due to a number of factors. I started first working with the Xcode tools when the iPhone SDK was back in beta (around March 2008), and since I didn't come from a Mac Cocoa background I was somewhat unfamiliar with using it.

This was not the major factor in my initial rejection of IB for iPhone development, though - Interface Builder for iPhone development during the initial iPhone SDK beta did actually suck and it was a pain to use However, the story is much different with today's iPhone SDK. While there are still certainly some annoying IB bugs, I've done a nearly complete 180Ëš with my attitude toward using Interface Builder. More often than not it is a good idea to use Interface Builder in your projects, I've found.It is a great tool now, and you should avail yourself of it Now, don't get me wrong - I am still firmly in the camp that believes that you should be able to implement anything you do in Interface Builder using code alone and I think being able to do so is invaluable.

Do not use Interface Builder as a crutch - you'll only hurt yourself (and your productivity or the quality of your products) in the end. While the drag-and-drop niceties of IB are great for 90% of what you'll need to do, when you have something custom to implement that can only be done in code, you'll either wish you had followed or be thankful for following this advice. I was lucky enough to hate IB long enough that I taught myself how to do everything in code alone, and then applied that knowledge back to IB Edit: To address the lack of reusability (perceived or real) with NIBs versus code...you won't be implementing something that is meant to be heavily reused in Interface Builder in all likelihood.

You can't really make a custom control or view in IB, so that's ruled out, and in most cases you're going to be implementing a view controller subclass that is built to address a specific purpose. You should of course always strive to make your code and associated resources as reusable as possible. This could include design considerations to ensure that you don't unnecessarily duplicate view controller subclasses that are very similar.

I was once very strongly against using Interface Builder in my own projects. This was due to a number of factors. I started first working with the Xcode tools when the iPhone SDK was back in beta (around March 2008), and since I didn't come from a Mac Cocoa background I was somewhat unfamiliar with using it.

This was not the major factor in my initial rejection of IB for iPhone development, though - Interface Builder for iPhone development during the initial iPhone SDK beta did actually suck and it was a pain to use. However, the story is much different with today's iPhone SDK. While there are still certainly some annoying IB bugs, I've done a nearly complete 180Ëš with my attitude toward using Interface Builder.

More often than not it is a good idea to use Interface Builder in your projects, I've found. It is a great tool now, and you should avail yourself of it. Now, don't get me wrong - I am still firmly in the camp that believes that you should be able to implement anything you do in Interface Builder using code alone and I think being able to do so is invaluable.Do not use Interface Builder as a crutch - you'll only hurt yourself (and your productivity or the quality of your products) in the end.

While the drag-and-drop niceties of IB are great for 90% of what you'll need to do, when you have something custom to implement that can only be done in code, you'll either wish you had followed or be thankful for following this advice. I was lucky enough to hate IB long enough that I taught myself how to do everything in code alone, and then applied that knowledge back to IB. Edit: To address the lack of reusability (perceived or real) with NIBs versus code...you won't be implementing something that is meant to be heavily reused in Interface Builder in all likelihood.

You can't really make a custom control or view in IB, so that's ruled out, and in most cases you're going to be implementing a view controller subclass that is built to address a specific purpose. You should of course always strive to make your code and associated resources as reusable as possible. This could include design considerations to ensure that you don't unnecessarily duplicate view controller subclasses that are very similar.

2 +1 Very well put. Understanding IB and MVC allows you to do whatever you need to if the need arises, but doing interfaces by hand will usually be a handicap rather than an advantage. The wise move is to decide based on the experience of your developers, the amount of non-standard functionality you're planning to implement, and the project itself.

Even with all these factors, I always do it in IB first, then only do it by hand if you can't do it in IB. – Quinn Taylor Nov 29 '09 at 22:31.

Using builders frees you of code that you would otherwise need to maintain and the less you need to maintain the better. The layouts built by IB do require some maintenance but it is a standard tool with its own documentation and its own online support (forums, lists, etc). If someone else ever needs to jump into your code, you can virtually guarantee they have experience with IB, but not necessarily your particular style of layout building.

It depends on your preference. I prefer to write it in code. I get to reuse the code.

Using a XIB/NIB generally breaks the one definition rule (if you are doing any customization). XIB/NIB maintenance is often more tedious and error prone (ODR). I really dislike maintaining button styles (example) for each button.

Circular references are more likely. Code/objects/ib instances are often less reusable/modular. Though I am the type to avoid a ui object that can do everything.

Deferred/ambiguous initialization order makes for a pretty scary state for clients, which they must never assume an object is ready for use or entirely initialized (unless you prefer to maintain those checks, which is a good way to waste time). If performance is important, guess which is faster? Resource management vs linker... seriously, I have written sub-programs and tests to verify nibs' existence in the bundle.

IB is great for prototyping and browsing object capabilities and appearances (I am not a graphic designer), though I think it is easiest to just write it in code once the prototype exists if you have any intention of maintaining or reusing it. My recommendation: Write highly reusable and stable code libraries, and use IB primarily for prototyping and one-offs. ====================== Responses: Sbrocket: I'm curious as to why you assert that circular references are more likely to occur as a result of using NIBs.

Sbrocket: I'll start by saying I've used Interface Builder since the Project Builder days (Xcode's predecessor). Lack of reliable structured ownership, identity, and initialization. I don't want ivars to be IB connections because it makes many classes difficult to use beyond 'the current context', In other words, it ties the code to the resource (more often than ideally).

Since you can't define initialization order or define initializers or additional initialization arguments in IB, you must then make the objects know about each other, creating circular dependencies and references. Sbrocket: or why lazy initialization (assuming that's in fact what you're referring to) is so scary when its relatively easy (or in fact automatic in many cases) to ensure that the object is initialized and connected. Re: scary I was not talking about lazy initialization.

I was talking about deferred and ambiguous initialization order. Nib initialization is semi-ordered. The actual order/process may vary, and this cannot be used reliably within reusable introspective programs... again, you'd end up writing too much code which is fragile, impossible to reuse, can never be assured to behave predictably, and must always validate state (yet another entry for circular dependence).

If it is not a one-off implementation, why bother with the complications? This approach to programming is chaotic and the implementations must (in turn) be prepared to handle anything at anytime. It is one thing to guard yourself from crashes, but to write defensive, production level code in this context... no way.It is far easier to write a consistent program which initialization determines the validity in context, which the implementations can then know (if initialized) that the object is generally prepared to be used.

Special-case complexity is minimized. Many such designs fall apart as program complexity increases, while library writers add layers upon layers of 'protective measures' just to keep gears moving - threading is a great entry for such heisenbugs. Unnecessary ambiguities are unwelcome in reusable production level code; humans shouldn't have to cross reference all of a program's special cases, and the complexities concerning defined behavior and special cases only spread or are ignored (assuming they are properly tracked and documented, which is more combined effort than writing it properly from the start).

I think we can all agree that onerous interfaces and implementations should be avoided. Sbrocket: I'd also be interested to see some hard numbers that show that NIB loading is slower - of course, it would seem to make sense at first thought, but we're always such bad predictors of performance bottlenecks without some hard testing. I never said (explicitly) that it was slower :) Ok, in seriousness, NIB unarchiving was (for me) a surprisingly slow process, though our ideas of slow and unarchiving times can vary dramatically.

Example: I had a document based app, and the nib loading was several times slower than the document loading, when document sizes were several times the nib size. Moving the implementation to code made the process much faster. Once it was on code and I had control of initialization order, I removed multiple multithreading complexities (checkpoints, locks, race condition entries, etc), which made document loading even faster.

Now that you have an explicit answer, I'll remind you that you have all the tools you need to measure performance. And please... remember that performance analysis and enhancements are learned, the number of excuses programmers use and get away with is... simply irresponsibility.

I'm curious as to why you assert that circular references are more likely to occur as a result of using NIBs, or why lazy initialization (assuming that's in fact what you're referring to) is so scary when its relatively easy (or in fact automatic in many cases) to ensure that the object is initialized and connected. I'd also be interested to see some hard numbers that show that NIB loading is slower - of course, it would seem to make sense at first thought, but we're always such bad predictors of performance bottlenecks without some hard testing. – Sbrocket Nov 30 '09 at 6:02 That's not to refute any of your points necessarily, that is, I'm just interested in some more detail on a few of your given points.

– Sbrocket Nov 30 '09 at 6:02.

Interface builder is great for a certain level of complexity. For things more or less complex, I would rather do it in code. If you have an interface that will not be used in more than one way, has several but not lots of elements, and does not need any tricky layout, than IB is great.In the long run, I almost never use IB.

That is as much the nature of the projects I work on as personal preference. There are definitely some interfaces that I would head straight to IB for, but I have not needed to create one of those in a while.

Unnecessary ambiguities are unwelcome in reusable production level code; humans shouldn't have to cross reference all of a program's special cases, and the complexities concerning defined behavior and special cases only spread or are ignored (assuming they are properly tracked and documented, which is more combined effort than writing it properly from the start). I think we can all agree that onerous interfaces and implementations should be avoided. Sbrocket: I'd also be interested to see some hard numbers that show that NIB loading is slower - of course, it would seem to make sense at first thought, but we're always such bad predictors of performance bottlenecks without some hard testing.

Ok, in seriousness, NIB unarchiving was (for me) a surprisingly slow process, though our ideas of slow and unarchiving times can vary dramatically. Example: I had a document based app, and the nib loading was several times slower than the document loading, when document sizes were several times the nib size. Moving the implementation to code made the process much faster.

Once it was on code and I had control of initialization order, I removed multiple multithreading complexities (checkpoints, locks, race condition entries, etc), which made document loading even faster. Now that you have an explicit answer, I'll remind you that you have all the tools you need to measure performance. Remember that performance analysis and enhancements are learned.

I cant really gove you an answer,but what I can give you is a way to a solution, that is you have to find the anglde that you relate to or peaks your interest. A good paper is one that people get drawn into because it reaches them ln some way.As for me WW11 to me, I think of the holocaust and the effect it had on the survivors, their families and those who stood by and did nothing until it was too late.

Related Questions