0

I'm building a Custom Container ViewController to house several instances of a nib. This nib holds a ViewController subclassed as DemoViewController

During the viewWillAppear of the Container, I perform the following:

- (void) viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    NSLog(@"Container will appear");


    if (_selectedViewController.parentViewController == self)
    {
        // nowthing to do
        return;
    }

    DemoViewController *vc = [[DemoViewController alloc] initWithNibName:@"Gauge" bundle:nil];

    NSArray *nibObjects = [[NSBundle mainBundle] loadNibNamed:@"Gauge" 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];

    // add as child VC
    [self addChildViewController:vc];

    [view1 addSubview:nibView];

    // notify it that move is done
    [vc didMoveToParentViewController:self];

}

During runtime, I receive the following exception:

2012-07-02 21:59:22.734 ContainerViewController[21747:f803] Loading Container View
2012-07-02 21:59:22.737 ContainerViewController[21747:f803] Container will appear
2012-07-02 21:59:22.740 ContainerViewController[21747:f803] Gauge View Loaded
2012-07-02 21:59:22.742 ContainerViewController[21747:f803] Gauge will move to parent controller
2012-07-02 21:59:22.743 ContainerViewController[21747:f803] -[DemoViewController superview]: unrecognized selector sent to instance 0x6a7daa0
2012-07-02 21:59:22.745 ContainerViewController[21747:f803] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[DemoViewController superview]: unrecognized selector sent to instance 0x6a7daa0'
*** First throw call stack:
(0x13c9022 0x155acd6 0x13cacbd 0x132fed0 0x132fcb2 0x4fe4f 0x4a14b 0x2d2c 0xdc38f 0xdc5eb 0xdd4ed 0x4aa0c 0x4ff92 0x4a14b 0x39550 0x39670 0x39836 0x4072a 0x11596 0x12274 0x21183 0x21c38 0x15634 0x12b3ef5 0x139d195 0x1301ff2 0x13008da 0x12ffd84 0x12ffc9b 0x11c65 0x13626 0x276d 0x26d5)
terminate called throwing an exception(lldb) 

Anyone have any idea what's going on here? Unfortunately, there's so little documentation on Container View Controllers, so I'm stumped.

Rob
  • 415,655
  • 72
  • 787
  • 1,044
Jonathan
  • 1,498
  • 2
  • 20
  • 41

3 Answers3

3

By the way, why are you trying to retrieve the view via the NIB at all? Why not the following?

childController = [[FirstContainedViewController alloc] initWithNibName:@"FirstContainedView" bundle:nil];
[self addChildViewController:childController];
[self.view addSubview:childController.view];
[childController didMoveToParentViewController:self];

This works for me and seems much simpler. I must not understand why you're doing what you're doing.

Rob
  • 415,655
  • 72
  • 787
  • 1,044
  • I know it's been a week since we last talked about this, but i seem to still be getting the same error when performing the containment like you suggested. : *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: '-[UIViewController _loadViewFromNibNamed:bundle:] loaded the "Gauge" nib but the view outlet was not set.' – Jonathan Jul 09 '12 at 22:53
  • Did you specifically set the childcontroller's view? – Jonathan Jul 09 '12 at 22:54
  • @shred444 Hmm. Have you tried using the NIB via a standard `presentViewController` or `pushViewController` to make sure your NIB has all of its outlets correctly hooked up? This sounds like the typical error I get when I forget to complete the NIB outlet configuration, which is all to easy to do (e.g. select the view in IB, look at its outlet, make sure it's hooked up to "File's Owner" and that "File's Owner" has its custom class hooked up to your view controller correctly). – Rob Jul 09 '12 at 23:01
  • Robert, while reading another thread, [link]http://stackoverflow.com/questions/7103130/in-xcode-im-getting-the-error-loaded-the-nib-but-the-view-outlet-was-not-set I found that you would normally create a new nib with view controller using the file>new and check the box for creating the nib. This worked! – Jonathan Jul 09 '12 at 23:05
  • @shred444 yeah, that will make sure your outlets are all correctly set up from the get go. But glad to hear you have it working. – Rob Jul 09 '12 at 23:10
2

It turns out, creating a nib by means of "Xcode's File->New->New File->Cocoa Touch->UIViewController subclass->with XIB for user interface" fixed my problem.

I was initially creating everything separately and linking them together by clicking on the frame of the nib and linking it to the view controller (like you would in storyboard). This turns out to be completely wrong.

Instead, you need to link the File's Owner to the ViewController file.

Thanks everyone for your help!

Jonathan
  • 1,498
  • 2
  • 20
  • 41
0

Your NSLog() illustrates the problem perfectly. The top level object of that XIB is obviously not a UIView, it's most likely the file's owner object, which points to DemoViewController. In calling the method, you've sent -addSubview to a View Controller.

CodaFi
  • 43,043
  • 8
  • 107
  • 153
  • interesting. So is it not possible for me to put a view controller inside a nib? – Jonathan Jul 03 '12 at 02:59
  • No, it's entirely possible to put a view controller inside a nib, you're just using the wrong object index. – CodaFi Jul 03 '12 at 03:00
  • I originally had vc.view instead of nibview, but that returned an error "loaded the "Gauge" nib but the view outlet was not set." - this can't be because I definitely set it – Jonathan Jul 03 '12 at 03:04
  • is it set from file's owner->view, or from an object->view – CodaFi Jul 03 '12 at 03:05
  • it's set from the object->view (and it's grayed out). – Jonathan Jul 03 '12 at 03:08
  • just try a higher index then. `UIView *nibView = [nibObjects objectAtIndex:1];`, or `UIView *nibView = [nibObjects objectAtIndex:2];` – CodaFi Jul 03 '12 at 03:20