Search code examples
iosnibidiomsviewcontroller

Conditionally presenting different nibs based on UI_USER_INTERFACE_IDIOM


I am upgrading an app to be Universal. I have a set of nibs to display a view controller (let's call it DetailViewController, that are specific to the iPhone and iPad.

Since I am supporting devices that are < iOS 4.0 I can't rely on just using an ~iPad suffix for the nibs to load the correct DetailViewController nibs, so I have a method that loads the nibs based testing for UI_USER_INTERFACE_IDIOM. This works except but it gets more complex as I present this view controller from two different source controllers: one is a table and the other is a graphical chart with buttons to call the the view controller and the format of the detail view is different based on which view controller calls it so I have two different sets of nibs, even though the interface and implementation files are the same for the DetailViewController.

To test this incrementally I have a method to do the test:

- (BOOL)loadNibFileForIdiom

{ NSArray* topLevelObjs = nil;

if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
    topLevelObjs = [[NSBundle mainBundle] loadNibNamed:@"DetailViewController~iPad" owner:self options:nil];
    if (topLevelObjs == nil)
    {
        NSLog(@"Error! Could not load myNib file.\n");
        return NO;
    }
    return YES;
}
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone) {
    topLevelObjs = [[NSBundle mainBundle] loadNibNamed:@"DetailViewController" owner:self options:nil];
    if (topLevelObjs == nil)
    {
        NSLog(@"Error! Could not load myNib file.\n");
        return NO;
    }
    return YES;
}
return NO;

}

As I say this works fine when the method is called in viewWillAppear of the detail controller and this view controller is pushed from the table view controller, which is actually called from a tab bar item. Note that the ChartViewController is also the first item on the tab bar.

In order to load the alternative nibs when called from either the table or the chart I've tried to add a conditional tests in this method wrapped around the code above thusly:

if (self.parentViewController == TableViewController) { ... do idiom tests and load appropriate nib for DetailViewController or DetailViewController~iPad nib }

and

if (self.parentViewController == ChartViewController) { ... do idiom tests and load appropriate nib for DetailViewController2 or DetailViewController2~iPad nib }

... but when doing these tests for which view controller the detail controller was pushed from they are not evaluated as true and the idiom tests are not run and so the nibs are not loaded.

What might I be doing wrong or what is a effective way to determine the controller that called the detail controller so that I can load the right nibs?


Solution

  • While I'm not still not sure how to solve this issue given the way I was trying to code it, I developed a workaround by adding a flag to my data model that gives me an indication of which source controller is passing the data to the detail controller and then basing my idiom test on the state of that flag.