“Application windows are expected to have a root view controller at the end of application launch” error only on iPad

StackOverflow https://stackoverflow.com/questions/8706828

Question

I am trying to convert my iPhone only application to a Universal application. I switched the devices to Universal and let Xcode do it's thing making a MainWindow-iPad.xib for me, and now when I run the app in the iPhone simulator it works fine, but when I run it in the iPad simulator I get a white screen and the Application windows are expected to have a root view controller at the end of application launch error. I have read some other posts about this same problem but none of them are just limited to one device.

Here is my application:didFinishLaunchWithOptions: method:

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

 /* some dropbox setup stuff */


// INIT VIEW AND CORE DATA
RootViewController *rootViewController = [[RootViewController alloc] initWithNibName:@"RootViewController" bundle:nil];

NSManagedObjectContext *context = [self managedObjectContext];
if (!context) {
    // Handle the error.
}

rootViewController.managedObjectContext = context;

UINavigationController *aNavigationController = [[UINavigationController alloc] initWithRootViewController:rootViewController];
self.navigationController = aNavigationController;

[_window addSubview:[_navigationController view]];
[_window makeKeyAndVisible];

[rootViewController release];
[aNavigationController release];

return YES;
}

EDIT: I just have one root view controller that is sized for iPhone called RootViewController. But it should still load in shouldn't it? Or if it shouldn't how do I create one for iPad?

Was it helpful?

Solution

Change the following line:

[_window addSubview:[_navigationController view]];

to:

_window.rootViewController = _navigationController;

or, if you need iOS 3 compatibility:

if ([_window respondsToSelector:@selector(setRootViewController:)]) {
    _window.rootViewController = _navigationController;
} else {
    [_window addSubview:_navigationController.view];
}

OTHER TIPS

You need to create a RootViewController with the xib file for iPad, otherwise you will get this error. Below are the template code provided by Xcode for universal app. If you debug the app in iPad simulator and point the debugger to run create the view controller with iPhone xib file, you will see the exact error.

- (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 = [[SYKViewController alloc] initWithNibName:@"SYKViewController_iPhone" bundle:nil];
    } else {
        self.viewController = [[SYKViewController alloc] initWithNibName:@"SYKViewController_iPad" bundle:nil];
    }
    self.window.rootViewController = self.viewController;
    [self.window makeKeyAndVisible];
    return YES;
}

In iOS 4 and later, UIWindow has the settable property rootViewController. This is the UINavigationController that pushes the UIViewController displayed on application launch. In Xcode IB, selecting Initial Scene: Is initial view controller for the UINavigationController sets everything up with no code required.

From the generated MainWindow-iPad.xib, in Interface Builder, add a View Controller object in IB, as well as an Object underneath the View. For the object, set it's class to AppDelegate, for the View Controller, set the class to ViewController (i the Identity Inspector) and specify the nib name in the Attributes Inspector. You can look at the MainWindow.nib for the device you were converting from to see the differences.

Edit: I forgot to mention some important steps. You will also need to set the File's Owner class to "UIApplication" in IB, and set the referencing outlets appropriately for the App Delegate and View Controller. Again, in IB, it's easiest to look at the Connections Inspector for the MainWindow nib you had and emulate it. If you have another nib specific to the iPad, other than MainWindow-iPad.nib (i.e. ViewController-iPad.nib), be sure to select it's File's Owner and point it to the view and set it's class appropriately too.

I tried your suggestions but none of them worked for me, sorry. :/ I ended up just making the view manually in code without interface builder:

if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad) {
    // Setup view for iPad
} else
    // Setup view for iPhone and iPod Touch
}

which I thought would be a lot harder than it actually was.

Note that if you use this method you can still hook up everything in interface builder and just change the frame of objects in these blocks if you are going to have the same objects on both iPhone and iPad.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top