superview and parentviewcontroller nil after adding a subview

deadroxy picture deadroxy · Jan 14, 2010 · Viewed 7.3k times · Source

I think I'm missing something fundamental and so I want to ask the community for some help. I'm building an app based around a basic iPhone Utility Application. My MainView and FlipsideView share some elements so I have created separate ViewControllers and nib files for those pieces. In order to do this I have done the following: 1. Created a viewcontroller called searchDateViewController which is the file's owner of searchDateView.xib 2. searchDateView.xib is basically a UIView with a UILabel inside, the view is wired up correctly 3. Inside both MainViewController.m and FlipsideViewController.m I add a subview as folllows:

- (void)loadView{
    [super loadView];
    searchDateViewController = [[SearchDateViewController alloc] initWithNibName:@"SearchDateView" bundle:nil];
    [[searchDateViewController view] setFrame:[searchDateView frame]];
    [[self view] addSubview:[searchDateViewController view]];

...
}

Everything displays and works just fine. Basically depending on actions that happen in each of the main and flipside views the UILabel of the nib is changed. However, I wanted to do something slightly different if the searchDateViewController is loaded from the MainView or the FlipsideView. However, I can't seem to figure out which ViewController is adding the searchDateViewController subview.

In searchDateViewController I tried:

- (void)viewDidLoad {
    [super viewDidLoad];
    NSLog(@"superview %@", self.view.superview);
    NSLog(@"parentviewcontroller %@", self.parentViewController);
}

In both cases I get nil.

So my question is - can I find out which ViewController is adding searchDateViewController a a subview? If so how? Or if my logic here is completely messed up, how should I be doing this?

Thanks!

Answer

Ole Begemann picture Ole Begemann · Jan 14, 2010

viewDidLoad is invoked when the view controller has loaded its view. In your case, that happends in this line:

[[searchDateViewController view] setFrame:[searchDateView frame]];

At that moment, you haven't yet called addSubview: so it is no wonder the view's superview is nil.

To solve your problem, you should define a property inside SearchDateViewController to distinguish between the different cases. This property would then be set accordingly by the parent controller that creates the SearchDateViewController instance.

Generally, I do not think it is a good idea to use a UIViewController subclass as a controller for a view that is used as a subview of one or several fullscreen views rather than be used as a fullscreen view itself. Much of UIViewController's logic works on the assumption that it is used to manage a fullscreen view. For instance, with your design, I think it's possible that SearchDateViewController will modify the view's frame when the device orientation changes etc. Since you don't need all this functionality for a non-fullscreen subview, I suggest you subclass your SearchDateViewController directly from NSObject.