Question

I have been spending time learning how to use the iPhone SDK. I've read "Beginning iPhone Development: Exploring the iPhone SDK" from cover to cover and I've never seen an example of multiple views within one XIB.

To illustrate what I mean, here is a screen shot of a XIB with the simple configuration of what I'm referring to:

alt text http://theopensourceu.com/wp-content/uploads/2009/04/one-xib-multiple-views.png

I figure that there has to be a very specific reason that I've never seen this. In Apple's examples and in all of my readings thus far, multiple XIBs are used with only a single 'view' (and sometimes the Navigation Controller or a Tab Bar Controller, etc). What is the reason for this? Should I avoid multiple views inside a XIB? What are the advantages or disadvantages to to either method?

Thank you in advance

Was it helpful?

Solution

It's a question of memory optimization and loading times. If you put all your views in one XIB, then when your application launches, it has to load the entire XIB into memory and construct all of the objects for all of the controls, and this takes a non-trivial amount of time.

If instead you separate your views into separate XIBs, then your app will start up much faster, because only the XIB containing the initial view will be loaded, and it will also use less memory at first. Then, when the view changes, you can load the XIB containing the new view lazily. This will incur a minor hitch when opening a view for the first time. If you're really trying to optimize memory use, you can also unload the previous view when switching views, but I wouldn't recommend this, as this will incur a hitch every time you switch views, instead of just the first time you switch to any given view.

OTHER TIPS

Following up on the previous answer, there are some times when you would like to load multiple views at the same time. Here's an example: You are displaying a report with multiple pages and you're going to use a UIScrollView to manage them. When the user is done browsing the report, he will close the report which will dismiss the view.

Create a UIScrollView in a XIB along with a UIView for each page you need. Since the UIViews are part of the XIB, they will be loaded into memory together, all at once, when the report is opened. Create two UIViewControllers and use them to display the page being viewed and the one being scrolled to. As the user moves through the pages, re-use the UIViewController on the page being scrolled away from to hold the page being scrolled to.

This will ensure great performance while the user is flipping through the pages. It loads all the pages at once up front into memory. I only uses two UIViewControllers, and it just changes which views are in them and moves them around.

This also has the great benefit of having all of the pages in one XIB. It makes it easier to edit, and quicker to load than separate XIB's. You just have to make sure you have the memory to load all the pages at once. If it's static content (such as in my case) it's a great way to go.

If you're looking for a good example of how to do this, I found this resource to be an excellent starting point:

http://cocoawithlove.com/2009/01/multiple-virtual-pages-in-uiscrollview.html

This is a warning to anyone trying to implement landscape and portrait with two views in a single XIB (iOS 4 with Xcode 4). The primary disadvantage of having two views in a single XIB–for me–was that you can only connect a single UIOutlet object in a XIB to a single UIOutlet object in a view controller.

So, for example, if you have a XIB with a view for landscape and a view for portrait, and both views contain the same interface objects in different positions (such as a UILabel in landscape and a UILabel in portrait). It is not possible to link the UILabel in your portrait view and the UILabel object in the landscape view to a single UILabel object in the view controller at the same time.

I find this a disappointment, as the iOS UIViewController documentation (iOS 4.3) suggested that I could implement custom landscape and portrait views by switching between two views programmatically as the screen rotates.

After spending quite some time to figure out how to do this, I discovered that it is possible to have two different views attached to a single view controller, but you need to have outlets for both views. For example, in my view controller, I have two UILabel objects (one to connect to a UILabel in the portrait view; one to connect to a UILabel in the landscape view). In my code, every time I update the landscape outlet, I also update the portrait landscape.

Not very elegant, but it works, and as this is for a simple view with one screen, it won't use up too much memory to have have all the UI objects duplicated in the controller and views. I wouldn't create a project that did it that way again, but it was a good enough work-around for that project.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top