tags:

views:

777

answers:

1

Hi,

I have a UIViewController with its own .xib, and I want to use a UISegmentedControl to display different information on the bottom half of the screen. I created a UIView in the container's .xib and connected it to a UIView property called detailView in the container's UIViewController.

I then created three .xib files in IB, one for the view that each segment needs to display in the detailView area.

I'm now stuck because I don't know how to load and unload the appropriate .xib file into the detailView area. Here's where I am:

- (void)segmentValueChanged:(id)sender {
    switch ([sender selectedSegmentIndex]) {
        case 0:
            // Unload whatever is in the detailView UIView and 
            // Load the AddressView.xib file into it
            break;
        case 1:
            // Unload whatever is in the detailView UIView and 
            // Load the ContactsView.xib file into it
            break;
        case 2:
            // Unload whatever is in the detailView UIView and 
            // Load the NotesView.xib file into it
            break;
        default:
            break;
    }
}

So how do I fill in the blanks and unload/load the detailView UIView properly?

Thanks!

--UPDATE--

The code in viewDidLoad is now: - (void)viewDidLoad { [super viewDidLoad];

    // Set the default detailView to be address since the default selectedSegmentIndex is 0.
    NSArray *nibObjects = [[NSBundle mainBundle] loadNibNamed:@"AddressView" owner:self options:nil];
    // assuming the view is the only top-level object in the nib file (besides File's Owner and First Responder)
    UIView *nibView = [nibObjects objectAtIndex:0];
    self.detailView = nibView;

    self.detailContainerView.autoresizesSubviews = YES;
    [self.detailContainerView addSubview:self.detailView];

    NSLog(@"self.view is %@", self.view);
    NSLog(@"self.detailContainerView is %@",self.detailContainerView);
    NSLog(@"self.detailView is %@", self.detailView);
}

And the debugger messages are:

self.view is UIView: 0x3a24d80; frame = (0 0; 320 460); autoresize = RM+BM; layer = CALayer: 0x3a35190
self.detailContainerView is UIView: 0x3a1aea0; frame = (20 57; 280 339); autoresize = W+H; layer = CALayer: 0x3a36b80
self.detailView is UIView: 0x3a24d80; frame = (0 0; 320 460); autoresize = RM+BM; layer = CALayer: 0x3a35190

Thanks!

+3  A: 

Use NSBundle's loadNibNamed:owner:options:. It returns an array of all top-level objects in the NIB file, which you can then assign to your ivars. If you need to distinguish between multiple objects in the array, give each one a unique tag in IB.

Try this:

case 0:
    [[NSBundle mainBundle] loadNibNamed:@"AddressView" owner:self options:nil];
    break;
...

If you have specified your view controller as File's Owner for AddressView.xib in Interface Builder, and have connected the view in the XIB to the view controller's detailView outlet, then the connection between the view and self.detailView should be in place after the call to loadNibNamed (because you specified self as the owner).

If that doesn't work, try something like this:

case 0:
    NSArray *nibObjects = [[NSBundle mainBundle] loadNibNamed:@"AddressView" owner:self options:nil];
    // assuming the view is the only top-level object in the nib file (besides File's Owner and First Responder)
    UIView *nibView = [nibObjects objectAtIndex:0];
    self.detailView = nibView;
    break;
...

Do the same for all cases in the switch statement. If you have declared detailView as @property (retain), the self.detailView = ... assignment will take care of releasing any formerly loaded views. There's no need to specifically unload the NIB contents.

Ole Begemann
I'm not quite sure how to put that together. Do I need to call `loadNibNamed:owner:options:` for each of the .xib's? Would it be possible to see some rough code to get an idea of how to do this? Thanks very much!
Neal L
I have added some code to my answer.
Ole Begemann
Ole, thanks for the great code! The only problem I'm running into is that when I call -loadNibNamed:owner:options the NIB is overlaid on top of the entire view it's supposed to be inside of. It seems that `self.detailView = nibView;` doesn't resize the loaded NIB to fit inside of the detailView that was set up in IB. Any ideas here? Thanks!
Neal L
No, of course it doesn't. `self.detailView = nibView;` is just a simple setter. You can adjust the view's position in code or you could place a blank UIView in your main view's nib and use it as a container and then do something like `[self.detailContainerView addSubview:self.detailView];`.
Ole Begemann
Even when I do this, the entire view is still being overlaid, and from the debugger it appears that the detailView has the same address as its parent. I've edited my original post to show the code and debugger messages... Thanks!
Neal L
Why did you make your detail view 320 by 460 pixels big when that is not what you want? Can't you just make it the correct size in IB?
Ole Begemann