Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dynamically load nib for iPhone/iPad within view controller

I have converted an iPhone application using the wizard like thing in XCode into a universal app.

It builds fine but obviously looks a bit rubbish in some areas :)

I need to load nibs according to which device is being used. I dont wish to create my view controllers using initWithNib as I already have code to create the controllers with some data (initWithMyLovelyData) which doesnt do anything to do with nib loading.

I know to find out the device you use UI_USER_INTERFACE_IDIOM() so I tried overriding the initWithNibName within the actual view controllers themselves, assuming they get called internally somehow. But it's not working as I guess I am unsure of the syntax.

I have tried

if(ipad..) self = [super initWithNibName:@"MyIpadNib" bundle:nibBundleOrNil];

And that doesnt work :/

EDIT - I know I have massively edited this, made my question a bit more specific after doing some more research - apologies!

like image 762
Chris James Avatar asked Jun 16 '10 10:06

Chris James


People also ask

What is a nib in iOS?

A nib file is a special type of resource file that you use to store the user interfaces of iOS and Mac apps. A nib file is an Interface Builder document.

What is file's Owner in xcode?

About the File's Owner One of the most important objects in a nib file is the File's Owner object. Unlike interface objects, the File's Owner object is a placeholder object that is not created when the nib file is loaded. Instead, you create this object in your code and pass it to the nib-loading code.


4 Answers

Actually, Apple does all this automatically, just name your NIB files:

MyViewController~iphone.xib // iPhone
MyViewController~ipad.xib // iPad

and load your view controller with the smallest amount of code:

[[MyViewController alloc] initWithNibName:nil bundle:nil]; // Apple will take care of everything
like image 192
Adam Avatar answered Oct 02 '22 13:10

Adam


EDIT: @Adam's answer below is the correct answer.

To determine which nib to load, do the following, and scrap your initWithMyLovelyData method and use a property to set the data. You should be able to easily move all your init code into the property setter method.

MyViewController *viewController;

if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
    viewController = [[MyViewController alloc] initWithNibName:@"ipadNIB" bundle:nil];
} else {
    viewController = [[MyViewController alloc] initWithNibName:@"iphoneNIB" bundle:nil];
}

viewController.myLovelyData = someData;
like image 44
kubi Avatar answered Oct 02 '22 14:10

kubi


I just put these two methods in a class called IPadHelper, and use the addIPadSuffixWhenOnIPad method to conditionally pick between two nibs depending on platform

+ (BOOL)isIPad{
    if (kCFCoreFoundationVersionNumber >= kCFCoreFoundationVersionNumber_iPhoneOS_3_2){
        if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad){
            return YES;
        }
    }
    return NO;
}

+ (NSString *)addIPadSuffixWhenOnIPad:(NSString *)resourceName{
    if([IPadHelper isIPad]){
        return [resourceName stringByAppendingString:@"-iPad"];
    }
    else {
        return resourceName;
    }   
}

see here http://cocoawithlove.com/2010/07/tips-tricks-for-conditional-ios3-ios32.html for more explanation of the first method...

like image 32
Dori Avatar answered Oct 02 '22 14:10

Dori


You can have your cake and eat it too. Just add a method that wraps initWithNibName:bundle: and adds your myLovelyData parameter:

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil  myLovelyData:(id)data
{
    if ((self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil])) 
    {
        // Custom initialization using myLovelyData
        //
    }
    return self;
}
like image 32
Bogatyr Avatar answered Oct 02 '22 13:10

Bogatyr