6

I have been trying to figure out why this has been happening but it seems that, in the iPad version of my universal app, it is loading the iPhone .xib instead of the iPad one.

I have named my iPhone xibs with a suffix of ~iphone.xib and I left my iPad ones just with .xib . I read to do that because someone said that worked for them but in my case it did not work for me!

Even if I do ~ipad.xib and ~iphone.xib for the different .xib files, it still loads the iPhone version!

**Is there any way to completely confirm that it is loading the iPhone version instead of the iPad version?

And is there any way to fix this issue so that the iPad loads the iPad .xibs?**

Thanks!

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {  

    self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];

// Override point for customization after application launch.
    self.viewController = [[[MyViewController alloc] initWithNibName:@"MyViewController" bundle:[NSBundle mainBundle]] autorelease];
    self.window.rootViewController = self.viewController;
    [self.window makeKeyAndVisible];
    return YES;
}
SimplyKiwi
  • 12,376
  • 22
  • 105
  • 191
  • It does work for me... Strange. But is the app really universal? Does it run in "fullscreen"? – fbernardo Mar 17 '12 at 21:44
  • Yes it does run full screen. The device families in the project settings and the target settings are both "iPhone/iPad". Do you use two different suffixes or which other way do you use? – SimplyKiwi Mar 17 '12 at 21:45
  • Controller~ipad.xib and Controller~iphone.xib and then in code I just call [[Controller alloc] initWithNibName:@"Controller" bundle:nil]; – fbernardo Mar 17 '12 at 21:51
  • Still no luck! Is there any way to NSLog the xib that the view actually loads with the suffix to confirm whether or not it is the ~iphone version or ~ipad version? – SimplyKiwi Mar 17 '12 at 22:07
  • Don't know, but that's weird. – fbernardo Mar 17 '12 at 22:10
  • Could there be anything else wrong that could be causing this? – SimplyKiwi Mar 17 '12 at 22:11
  • Is this for the first view controller in the app? If not, how are you creating the view controller? In code? (show the code) Storyboard? – jsd Mar 17 '12 at 22:41
  • The same way apple does in their templates like this: self.viewController = [[[MyViewController alloc] initWithNibName:@"MyViewController" bundle:nil] autorelease]; – SimplyKiwi Mar 17 '12 at 22:42
  • I would recommend setting bundle to [NSBundle mainBundle]. This could cause some errors. And if you could post the whole code where you are initializing the view controller and presenting it, it would be easier to find the error. – Dominik Hadl Mar 17 '12 at 22:46
  • Nope that didn't fix it. I will add my code above now. – SimplyKiwi Mar 17 '12 at 22:53
  • I'll post a workaround which should work in an answer below. – Dominik Hadl Mar 17 '12 at 22:57

2 Answers2

4

In my app, I do it like this. I create separate .h, .m and XIB files for iPad views and then in AppDelegate I simply make an if condition, which decides which view controller it will show.
Btw. I don't use those suffixes on XIBs, I name them to what I want to.

My AppDelegate.h file (a part of it)

 @class FirstViewController;
 @class FirstIpadViewController;    
 .......
 .......
 @property (nonatomic, retain) IBOutlet FirstViewController *viewController;
 @property (nonatomic, retain) IBOutlet FirstIpadViewController *ipadViewController;

My AppDelegate.m file (a part of it)

if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone) {
    self.window.rootViewController = self.viewController;
    [self.window makeKeyAndVisible];
} else {
    self.window.rootViewController = self.ipadViewController;
    [self.window makeKeyAndVisible];
}

This should definitely do it. Just change the class and the property in .h file, to your view controller and you should be good to go :)

EDIT

I have just found out how to do it. And the proper naming conventions are _iPhone and iPad. This is basically the same as I posted above, only change is that it will have the same .h and .m files, but different XIBs.

In the AppDelegate .m file

    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    // Override point for customization after application launch.
    if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
        self.viewController = [[ViewController alloc] initWithNibName:@"ViewController_iPhone" bundle:nil];
    } else {
        self.viewController = [[ViewController alloc] initWithNibName:@"ViewController_iPad" bundle:nil];
    }
    self.window.rootViewController = self.viewController;
    [self.window makeKeyAndVisible];
    return YES;
}
Dominik Hadl
  • 3,609
  • 3
  • 24
  • 58
  • Sadly I use one class for both xibs so how would I do this workaround with that? Also I do not have a mainWindow.xib for connecting the IBOutlets, I just connect it programmatically. – SimplyKiwi Mar 17 '12 at 23:33
  • Oh I see! So it isn't ~iphone.xib and ~ipad.xib but instead _iPhone.xib and _iPad.xib? – SimplyKiwi Mar 17 '12 at 23:39
  • Yes and the code has to be the same as I posted above (the code under EDIT headline). – Dominik Hadl Mar 17 '12 at 23:41
  • Sadly it does not work. First I have 2 questions: 1. Should I still do NSBundle mainBundle? 2. Should I do autorelease inside those conditional statements? Also this is the crash I get: *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Could not load NIB in bundle: – SimplyKiwi Mar 18 '12 at 05:04
  • I ended up fixing everything, it had to do with my xibs not being compiled correctly during the build and I had to do a fresh clean of the project and now it works perfectly, thanks for help and info! – SimplyKiwi Mar 18 '12 at 06:24
0

This solution works with Storyboards while using your own custom xibs. It reuses the same .h & .m files for the views:

  • ViewController.h
  • ViewController.m
  • ViewController.xib
  • ViewController~iPad.xib

In your ViewController.m file add:

- (id)initWithCoder:(NSCoder *)aDecoder
    {
        if (self)
        {
            NSString* nibName = NSStringFromClass([self class]);
            if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone)
            {
                self = [super initWithNibName:nibName bundle:nil];
            }
            else if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad)
            {
                self = [super initWithNibName:[nibName stringByAppendingString:@"~iPad"] bundle:nil];
            }
            return self;
        }
        return self;
    }

Just check the xibs have the File's Owner View Controller Custom Class name set and the view outlet set.

David Douglas
  • 10,377
  • 2
  • 55
  • 53