Objective-c – Loading a Nib within a Nib

iphoneobjective c

I am new to interface builder and I would like to have a screen which contains a 3×3 grid of a UIView each of which contain a UIImageView, and 4 UILabels.

My logic is probably flawed but the way I am trying to achieve this was to:

  1. Create a UIView Nib file MyUIView.nib and layout in IB with an imageView and 4 labels
  2. Create a UIView subclass called MyUIView.m which contains 1 IBOutlet UIImageView and 4 IBOutlet UILabels. Link the MyUIView.nib and MyUIView.m as files owner and connect the outlets.
  3. Then create another nib MyGridViewController.nib which has 9 MyUIView in it laid out in the 3×3 grid.
  4. Create a UIViewController which has 9 IBOutlet MyUIView and connect them via Interface Builder.

Is it possible to load a nib into another nib graphically from within InterfaceBuilder, if so how do I do it? Do I drag a "standard" UIView onto the canvas and then change the class to be a MyUIView?

Or do I need to do this all programmatically within the MyGridViewController.m with something like:

for (int i=0; i<9; i++)
{
    NSArray* nibViews =  [[NSBundle mainBundle] loadNibNamed:@"MyUIView" owner:self options:nil];
   [myViewArray addObject:[ nibViews objectAtIndex: 1]];
}

The only other way I have gotten this to work was to have a single Nib and put 9 UIImageViews and 36 UILabels but this obviously is a pain when I want to change something as I need to update each one of the 3×3 "cells". I thought it would be easier to change it in one file and all 9 would be updated.

Best Answer

You cannot do it in Interface Builder.

What I would probably do is to make a custom view, say MyGridItem, that loads MyUIView.nib as a subview when it awakes, and then use 9 of them in your MyGridView.nib.

Be careful with awakeFromNib, as it can be called twice if the view is involved in the loading of two different nibs (eg, if MyGridItem is the owner when loading MyGridView.nib, then MyGridItem awakeFromNib will be called once when it is loaded as part of loading MyUIView.nib, and once when it loads the MyGridView.nib.

Also, since you're loading the nib 9 times, you may want to cache the nib once using

NSNib* theNib = [[NSNib alloc] initWithNibNamed:@"MyGridItem" bundle:nil];

load it with:

if ( [theNib instantiateNibWithOwner:self topLevelObjects:NULL] ) {

You then may want to deallocate it after you've loaded all nine subviews.

Related Topic