views:

400

answers:

2

For instance:

  1. Create a new UIVC using initWithNibName, using "nib-v1"
  2. Display it, e.g. using [(UINavigationController) nav pushViewController: myVC]
  3. Change the NIB that myVC is using to "nib-v2"

So far as I can see, this is the "correct" approach to app-design for a lot of apps, when paging through information where you need two slightly different UI screens for the info being displayed.

For instance, most of your pages are text, but some of them have an image too (think of an RSS reader, where some RSS entries have text + image, some are text only).

I've dealt with this previously by having one NIB file with a second, invisible, named UIView instance that I layered over the top of the first one, and switched on/off depending on on context, using the "hidden" flag.

But this is clearly wrong, and wastes memory.

However, I cannot see an obvious way to "reload" the view from the NIB file. I'm guessing I want to somehow reproduce the magic that initWithNibName does?

I suspect this is possible, but I'm sure that if you do it "the wrong way" then the app will simply crash horribly.

A: 

You shouldn't change what NIB file a UIViewController uses. Attaching the NIB to the UIViewController should be a one-time event. The hidden views are fine; they're certainly not clearly wrong. You can also programmatically add view elements after loading. If you're doing a lot of that, you can skip the NIB entirely and programmatically build the view in -loadView. Any of these are fine, but don't switch the NIB after initialization. I don't even recommend having multiple NIBs that you choose between for a given UIViewController class; it's just too confusing. Generally each NIB should map to a dedicated UIViewController class with a very similar (or identical) name.

In a related note, I recommend moving the name of the NIB into the UIViewController, as described in an earlier posting.

Rob Napier
Thanks, but loadView defeats the purpose of using NIB files, so that doesn't help here. I work with teams of non-programmers, who need to edit GUI's, so that we have to use NIB files for everything.(which works well, most of the time, until you run into situations like this where Apple's lack of foresight kicks in. Sadly, these situations are a bit more common than I'd hoped :( ).
Adam
+1  A: 

I agree with Rob, but if you really want to mess with swapping nib's (which is bad as it can easily lead to dangling pointers and the like), you could maybe load the view from the new nib with NSBundle's - (NSArray *)loadNibNamed:(NSString *)name owner:(id)owner options:(NSDictionary *)options method and do the view swapping yourself.

You should rather use different view controllers for different types of content. If they only differ slightly, you can still consider creating one base class and subclassing the different variations.

MrMage
"which is bad as it can easily lead to dangling pointers" -- do you know of any specific examples of how this could happen? I'm assuming that a 100% correct approach *might* be to re-write Apple's NIB-loading code (which uses introspection, AFAICS) - since it already walks the object tree, it would prevent any such problems - no? yes? I'm thinking of trying this, but I don't know how much trouble I'm letting myself in for :)
Adam
I've been using this technique for a while now on different projects, and it's consistently worked fine. I never encountered problems with dangling pointers.
Adam