views:

515

answers:

2

As a newbie, IB and all the possible connections is bewildering to me. Most tutorials I've found are what I'd call the reincarnation of spaghetti code, in which the entanglement is all the connections created by dragging. Of course, I want to use IB for layout of views (sizing & placing visual elements), that's what IB is great for. But a controller is not a view, so it's less confusing if all my controllers are solely code and don't appear anywhere in IB. I suspect this will minimize the spaghetti. It also encourages the one-xib-per-view admonishment. To that end, and here's the question, where can I find example projects that adhere to this strategy?

+1  A: 

Good question. The pattern I try to stick with is making the controller in code, adding IBOutlets and IBActions for the things in the XIB/NIB that interact with that code, and a thing in the controller's constructor which loads the XIB/NIB with "self" as the owner, and in IB I connect stuff to the "File's Owner" placeholder, whose identity I will have specified to be the my controller's class.

harms
+2  A: 

I don't have a set of sample projects, but I will give you some information about how things work and when you should create controller's in a XIB file or in code.

If your controllers are created dynamically by way of a user's action, you typically won't instantiate them in a XIB file. Instead, you'll instantiate them in code like harms mentions above. Once you do that, you'll still need a mechanism to connect this controller that was created in code, to the user interface elements that you've created in IB.

The mechanism that IB provides for solving this is the File's Owner. Mastering the File's Owner is essential to "getting" Interface Builder.

The file's owner is not an object that is "in" the XIB file, it's an object that's represented in the XIB file. It's a placeholder for an object that will already exist when the XIB file is loaded. When NIB files are loaded at run time, they're loaded with the NSBundle method -[NSBundle loadNibNamed:ownwer:options:]. The owner parameter is used to resolve the file's owner placeholder object in the XIB/NIB file. When the file is loaded at runtime, all of the connections made against the file's owner will resolve against the object you passed in as the owner parameter to the NSBundle method. On the iPhone, you typically don't load NIB file yourself. Instead UIViewController does it for you. The default implementation of UIViewController's loadView method might look something like this:

- (void)loadView {
    [[self nibBundle] loadNibNamed:[self nibName] owner:self options:nil];
}

So, by connecting the elements in your XIB file to the file's owner, you'll be connecting them to your view controller.

You will have some controllers that are statically in your application - they'll be alive forever. A navigation or tab controller along with their root items are typically alive for for the entire life of their application. When that's the case, I'd set those view controllers up in the MainWindow.xib file. Most of the other controllers would be created dynamically, and programatically in response the the user doing things.

Jon Hess
Thanks, Jon, that's helpful info. I still want to try the strategy of never having controllers on the IB side. Would you agree that it's do-able? I'm still searching for code examples...
Doug
Everything's doable. But I would recommend the approach I listed above. Create static controllers in the MainWindow.xib file, and create most(usually all) of the other controller in code in response to user actions.
Jon Hess