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

烂漫一生 提交于 2019-11-27 13:35:55

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];
}

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.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!