my app up to iOS 7 works correctly. I tried it today with Xcode 6 and when I run it I have a nasty surprise :(:
You can see that Xcode now draw my viewController as if it is in portrait mode but as you can see is in landscape mode.
Do you know what is changed in iOS 8? :/
I used the following orientation methods:
(NSUInteger)supportedInterfaceOrientations
(BOOL)shouldAutorotate
(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
EDIT:
I just discover this method:
- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window
{
return UIInterfaceOrientationMaskLandscape;
}
And now my first viewcontrollers works correctly :). the problem is when I show a modal (that change the set of method in UIInterfaceOrientationMaskAll) remake the ugly effect of screenshot.
Precisely i change my methods in this mode:
- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window
{
if(self.restrictRotation)
{
return UIInterfaceOrientationMaskLandscape;
}
else
{
return UIInterfaceOrientationMaskAll;
}
}
// THIS IS A DELEGATE OF MODAL VIEW CONTROLLER
- (void)updateInterfaceAfterDocumentPreviewViewController
{
NSLog(#"updateInterfaceAfterDocumentPreviewViewController");
[[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationLandscapeLeft];
AppDelegate* appDelegate = (AppDelegate*)[UIApplication sharedApplication].delegate;
appDelegate.restrictRotation = YES;
}
Please try the following code
In the didFinishLaunchingWithOptions of AppDelegate
self.window.rootViewController = self.viewController;
[self.window makeKeyAndVisible];
[self.window setFrame:[[UIScreen mainScreen] bounds]]; //Add
The issue seems to be the order of calls when you set up the window. You need to call makeKeyAndVisible before you assign the rootViewController in your didFinishLaunchingWithOptions method on the app delegate. The following works:
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
[self.window makeKeyAndVisible];
self.window.rootViewController = self.myMainViewController;
But if you change the order to:
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
self.window.rootViewController = self.myMainViewController;
[self.window makeKeyAndVisible];
You get the behavior you are experiencing.
I had the same exact problem with a "Loading screen". This is what worked for me. (Please note: my App only supports iOS 7 or later, landscape mode.) :
CGRect theFrame = self.view.frame;
if ([[[UIDevice currentDevice] systemVersion] floatValue] < 8.0) {
CGRect screenBounds = [[UIScreen mainScreen] bounds];
theFrame.origin = CGPointZero;
theFrame.size.width = screenBounds.size.height;
theFrame.size.height = screenBounds.size.width;
}
NSLog(#"%#", [NSNumber valueWithCGRect:theFrame]);
self.loadingScreen = [[UIView alloc] initWithFrame:theFrame];
Please refer to Mike Hay's answer if your App supports portrait orientation and for the "long way to calculate the correct applicationFrame":
https://stackoverflow.com/a/18072095/4108485
Hope this helps.
Have a look at your .plist file.
Make sure you have "Initial interface orientation" set as the orientation you wanted.
In the "Supported interface orientations", have the preferred orientation as the first entry on the list (looks like apple changed this order).
I was having a similar problem, I couldn't get the right Launch Images to show (I had two for iPad, Default-Portrait.png and Default-Landscape.png) and I also couldn't get the App itself to auto orient after the Launch Image disappeared.
To solve the problem for the Launch Images:
Go to the Custom iOS Target Properties section of the project (Click on your Project's Icon at the top of the list of project files, and it should be the first section you see).
Add a row to that table called "Launch image" (should autofill) and enter "Default" as the string in the right column.
Make sure your Launch Images follow Apple's filename guidelines (ie: Default-568#2x, Default#2x, etc) check this SO answer
To solve the app orientation issue at first ViewController:
Go to your projects plist file (should be "YourApp-Info.plist")
Add a row and enter "Supported interface orientations"
Add the orientations that your app supports
That approach to detecting orientation was deprecated in iOS8 (but still allowed for now).
It was replaced with the concept of Size Classes and Trait Collections.
(Oddly, I can't seem to find a Size Class Reference in Apple's docs online right now - would swear it was there before - maybe in XCode). See here for WWDC videos.
Anyway, there's a checkbox in Interface Builder that says "Use Size Classes."
Could be you have that checked. Turn it off & see if that helps?
Oldschool solution:
BOOL portrait;
BOOL iOS8OrLater = ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0);
if (iOS8OrLater) {
CGFloat height = CGRectGetHeight(self.view.frame);
CGFloat width = CGRectGetWidth(self.view.frame);
if (width / height > 1.0) {
portrait = NO;
} else {
portrait = YES;
}
} else {
portrait = UIInterfaceOrientationIsPortrait(self.interfaceOrientation);
}
if(portrait) {
[self layoutPortrait];
} else {
[self layoutLandscape];
}
You can call this in viewWillLayoutSubviews
UIInterfaceOrientation currentOrientation = [UIApplication sharedApplication].statusBarOrientation;
if( UIDeviceOrientationIsLandscape( currentOrientation ) )
{
if( UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad )
{
[[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationPortrait];
// -- Fix for rotation issue for ios 8
if( IS_IOS_8_OR_LATER )
{
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"MainStoryboard_iPad"
bundle: nil];
// -- Set frame of nav controller
UINavigationController *nc = [storyboard instantiateViewControllerWithIdentifier:#"NavController"];
self.window.rootViewController = nc;
[self.window setFrame:[[UIScreen mainScreen] bounds]];
// -- Set fame of home view controller
UIViewController *vc = [storyboard instantiateViewControllerWithIdentifier:#"Home"];
self.window.rootViewController = vc;
[self.window makeKeyAndVisible];
[self.window setFrame:[[UIScreen mainScreen] bounds]];
}
}
}
Related
I want to know how to set up the app delegate in my Xcode project so that the generic view controller files (ViewController.h and .m) will be the files that control the root view controller I set in my app delegate.
My AppDelegate.h
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
CGRect rect = [[UIScreen mainScreen] bounds];
self.window.frame = rect;
planet3dController *theController;
self.controller = theController;
self.window.rootViewController = self.controller;
GLView *glView = [[GLView alloc] initWithFrame:rect];
[self.window addSubview:glView];
theController.view=glView;
glView.controller = self.controller;
glView.animationInterval = 1.0 / kRenderingFrequency;
[glView startAnimation];
glView.layer.contentsScale = [UIScreen mainScreen].scale;
return YES;
}
self.window.rootViewController = self.controller;
It looks like you are already doing just that.
I don't know what your app is trying to do, but [self.window addSubview:glView]; is somewhat suspicious. You probably want to add glView as a subview of your rootViewController, not the window, right?
If you want the initial "generic" view controller files to be the rootViewController, then don't override it with your specialized planet3dController one like you are currently doing in the example, but set it to an instance of that controller.
I have an empty application and there is no storyboard or xib involved. I want to have a hidden status bar and support only landscape orientation. Again, I wan't to make those changes only within code and don't touch the Info.plist.
Problem
I create a UIWindow with a controller that says the only supported orientation is landscape. In that case my UIWindow is created in the dimension of portrait mode and doesn't rotate. The expected result would be a screen that is completely cyan.
This is my delegate:
#import "AppDelegate.h"
#import "AppViewController.h"
#implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
self.window.backgroundColor = [UIColor cyanColor];
self.window.rootViewController = [[AppViewController alloc] init];
[self.window makeKeyAndVisible];
return YES;
}
#end
This is my controller:
#import "AppViewController.h"
#implementation AppViewController
- (BOOL)shouldAutorotate {
return YES;
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
return UIInterfaceOrientationLandscapeLeft;
}
- (BOOL)prefersStatusBarHidden {
return YES;
}
- (NSUInteger)supportedInterfaceOrientations {
return UIInterfaceOrientationMaskLandscape;
}
#end
What I've tried so far
If I set the rootViewController after calling makeKeyAndVisible everything seems to work at first.
self.window.backgroundColor = [UIColor cyanColor];
[self.window makeKeyAndVisible];
self.window.rootViewController = [[AppViewController alloc] init];
There are still some issues. First of all I don't like this since it seems to be very fragile. Second problem is that in a more complex application that sets a GLKViewController as the rootViewController I get the following result (expected would be no black area on the left):
It looks like the status bar is not hidden early enough. Several gesture recognizers are active and in the GLKViewController and clicking on the black area yields the following log message:
2014-09-25 13:20:42.170 StackOverflowExample[6971:107907] unexpected nil window in
_UIApplicationHandleEventFromQueueEvent, _windowServerHitTestWindow: UIClassicWindow: 0x7fa20b805e00; frame = (0 0; 375 667);
userInteractionEnabled = NO; gestureRecognizers = NSArray:
0x7fa20b80a620; layer = UIWindowLayer: 0x7fa20b806890
I also performed various other changes, like attaching an empty UIViewController and adding my view as a sub-view. In that case my view looks correct but the window is still using the wrong dimensions.
Everything rotates correct if I do not override the supportedInterfaceOrientations methods in my view controller. But that is of course not what I want.
When you run landscape app from portrait mode UIScreen has portrait bounds in iOS 8 (only if you haven't this app in app switch panel, as iOS 8 makes some cache). Even displaying window with makeKeyAndVisible doesn't change it's frame. But it changes [UIScreen mainScreen].bounds according to AppViewController avaliable orientation.
#import "AppDelegate.h"
#import "AppViewController.h"
#implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Portrait bounds at this point
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
self.window.backgroundColor = [UIColor cyanColor];
self.window.rootViewController = [[AppViewController alloc] init];
[self.window makeKeyAndVisible];
return YES;
}
#end
So let's change window's frame after [self.window makeKeyAndVisible]
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
self.window = [UIWindow new];
self.window.backgroundColor = [UIColor cyanColor];
self.window.rootViewController = [[AppViewController alloc] init];
[self.window makeKeyAndVisible];
// Here it is
self.window.frame = [UIScreen mainScreen].bounds;
return YES;
}
I think that it is iOS 8 bug.
I had a similar problem, for a portrait-only app.
I fixed the problem by setting status bar orientation BEFORE instantiate the UIWindow
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Init my stuff
// ...
// Prepare window
[application setStatusBarOrientation:UIInterfaceOrientationPortrait animated:NO]; // prevent start orientation bug
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
[self.window makeKeyAndVisible];
return YES;
}
In your case, you should use UIInterfaceOrienationLandscapeLeft (or Right) in the setStatusBarOrientation:animated: method.
Hope it helps you.
Personally, none of the solution presented above worked. I finally set "hidden" to YES for the window in my main xib, as first suggested here: unexpected nil window in _UIApplicationHandleEventFromQueueEvent, _windowServerHitTestWindow
You can rotate UIWindow by adding single line only.
You can set the rootController for your UIWindow. e.g:
fileprivate(set) var bottonOverlayWindow = UIWindow()
self.bottonOverlayWindow.rootViewController = self;
// 'self' will the ViewController on which you had added UIWindow view. So whenever you ViewController change the orientation, your window view also change it's orientation.
Let me know if you face any issue.
The problem is solved when adding a Launch Screen, which you can only do by adding an extra property to the info.plist
had this problem myself, i'm not sure if you can add it through code though, i only managed to make it work with info.plist + Launch Screen xib file
<key>UILaunchStoryboardName</key>
<string>Launch Screen</string>
Actually i don't think you have to add a xib file, if just the key (with any value) is available in the plist it should work.
None of the solutions posted here or elsewhere worked for me.
However, I found that this issue apparently does not occur with Storyboards, so an alternative solution is to move away from xibs. (This fact sadly also makes it unlikely that Apple will take the problem seriously.)
I just opened my iPad project on XCode 4.5. My app is designed to run in Landscape mode. It works perfectly on previous versions of XCode. But on XCode 4.5, it is rotated of 90° (quarter turn) with a empty area on the right side of the screen (and my view has the correct size but goes out of the screen). It looks like this:
I checked the following posts but didn't help:
orientation issue in ios6
ios6 Rotation issue from landscape to portrait mode
Set orientation to landscape mode in xcode 4.5 GM IOS 6
Anybody had this issue ?
Any help would be appreciated !
Thanks everybody for your replies. I finally found a solution.
First, check that all your launch images have the correct orientation and correct size in the target summary menu (blue icon of your project => target => summary => scroll at the bottom) ; if the size or orientation is not correct, you get a warning on the launch image which is not set properly.
Up to now, I had a project with this structure (old XCode fashion):
AppDelegate.h and .m
RootViewController.h and .m
a MainWindow-Iphone.xib and MainWindow-iPad.xib (with the RootViewController linked in Interface Builder ; see the screenshot below with the yellow/brown icon (with a square inside) relative to the RootViewController)
Here below a screenshot of what it looked like:
And here is what was the code in the applicationDidFinishLaunching: method of my AppDelegate:
- (void)applicationDidFinishLaunching:(UIApplication *)application {
[window addSubview:[rootViewController view]];
[window makeKeyAndVisible];
}
What I did is to be closer to the structure you get when you create an empty project with XCode 4.5. Consequently:
I removed the MainWindow.xib and MainWindow-iPad.xib and now created my window programatically (clearer and better to make sure that it fits the size of any screen)
I removed the "Main nib file base name" and "Main nib file base name (iPad)" keys which were defined in my Info.plist (and set to MainWindow.xib and MainWindow-iPad.xib)
I added empty RootViewController_iPhone.xib and RootViewController_iPad.xib
I changed the code in my applicationDidFinishLaunching method like this:
- (void)applicationDidFinishLaunching:(UIApplication *)application {
NSLog(#"applicationDidFinishLaunching");
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
self.rootViewController = [[RootViewController alloc] initWithNibName:#"RootViewController_iPhone" bundle:nil];
} else {
self.rootViewController = [[RootViewController alloc] initWithNibName:#"RootViewController_iPad" bundle:nil];
}
self.window.rootViewController = self.rootViewController;
[self.window makeKeyAndVisible];
}
And now, everything works fine ! Orientation is correct on iPad ! And it is much more clear than before :) I even didn't have to change the deprecated methods like
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
By the way, to make sure that all your views will be full screen (on iPhone 5) make sure that your views are set to the mode "Scale to fill" in Interface Builder and that "Autoresize subviews" is clicked. If some of your views do not scale to full screen, it is probably due to the order in which one you create your controllers/views (the superView sends a notification to its subviews only when it (the superView) is created). To solve this easily, simply add the following code in the - (void)viewDidLoad method:
CGRect screenBounds = [[UIScreen mainScreen] bounds];
[self.view setFrame:CGRectMake(0,0,screenBounds.size.width,screenBounds.size.height)];
or use:
[self presentModalViewController:myViewController animated:TRUE];
instead of:
[self.view.superview addSubview:myViewController.view];
presentModalViewController indeed sends a resizing notification to the subviews.
Hope this will help !
Make sure you are setting the window.rootViewController as well. I had the same issue, but this line fixed it for me:
MainViewController *mainView = [[MainViewController alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
window.rootViewController = mainView;
I had a similar problem on an app I upgraded. I haven't found it documented but it seems there has been a change. What I ended up finding is the new window doesn't seem to know about rotation or size until after it is made key and visible. I was able to move my frame setting to immediately after makeKeyAndVisible and everything worked. I hope that helps you.
[[yourViewController view] setFrame:CGRectMake(0.0, 0.0, 1024.0, 768.0)];
[[yourViewController view] setTransform:CGAffineTransformTranslate(CGAffineTransformMakeRotation(0.5*M_PI),128.0,128.0)];
If you are using Storyboards one easy hack is to use the loadView method. It is called before viewDidLoad. Just go to your Storyboard and delete the associated view as you are going to create it programmatically in loadView. Then return to the view controller class and copy the following code:
- (void)loadView
{
// You can adjust the view size and location here. If using full screen use the following code. If you have a tab bar for example and also want to account for the top default iPad bar, use: CGRectMake(0, 20, 1024, 699) instead.
UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 1024, 748)];
view.backgroundColor = [UIColor whiteColor];
view.autoresizesSubviews = NO;
self.view = view;
}
A few simple steps in order will solve this problem for you.
First, in AppDelegate.m, check if you're adding your rootViewController as a subView. That is, instead of this,
- (void)applicationDidFinishLaunching:(UIApplication *)application {
[window addSubview:[navigationController view]];
[window makeKeyAndVisible];
}
do something like this
- (void)applicationDidFinishLaunching:(UIApplication *)application {
window.rootViewController = navigationController;
[window makeKeyAndVisible];
}
if you're setting a navigation controller as your root view controller.
Second, if you need to get control of the rotation methods within your navigationController's pushed viewControllers, create a category for UINavigationController like so:
#import "UINavigationController+Rotation.h"
#implementation UINavigationController (Rotation)
- (BOOL)shouldAutorotate {
BOOL result = self.topViewController.shouldAutorotate;
return result;
}
- (NSUInteger)supportedInterfaceOrientations {
return self.topViewController.supportedInterfaceOrientations;
}
#end
Now, these two orientation methods for iOS 6 upwards
-(BOOL)shouldAutorotate and
-(NSUInteger)supportedInterfaceOrientations
will get called within your classes.
This is necessary because the older rotation methods such as
-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
have been deprecated from iOS 6.
So lastly, you'll need to implement these in your view controllers; something like this:
-(BOOL)shouldAutorotate
{
return YES;
}
-(NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskAll;
}
if you want to allow your view controller to rotate and support all orientations.
The other orientation masks are:
UIInterfaceOrientationMaskPortrait
UIInterfaceOrientationMaskLandscapeLeft
UIInterfaceOrientationMaskLandscapeRight
UIInterfaceOrientationMaskPortraitUpsideDown
UIInterfaceOrientationMaskLandscape and
UIInterfaceOrientationMaskAllButUpsideDown
I am developing a xib-based landscape-only app. The app launches in landscape correctly. However, the view in my main ViewController is presented in portrait. That is, it is rotated 90 degrees so that the image appears cropped and does not take up the entire screen. If I use my interface to present a modal view controller then return to the main ViewController, the issue corrects itself (the view is presented in landscape). This problem did not occur under Xcode 4.2. It occurred after upgrading to Xcode 4.3, and the only code changes that were made were automatically implemented by Xcode when I upgraded the project settings.
Based on advice in other posts, I verified my Info.plist settings for Supported Interface Orientations and Initial Interface Orientation. I overrode the shouldAutorotateToInterfaceOrientation method for each of my view controllers to return YES only for landscape orientations. Also, I turned off auto resizing for the view, as I never want the size/orientation of the view to change.
Based on the ideas in this link [1], I suspected the problem is that the view is not receiving the call to change orientation at launch, possibly due to the removal of the MainWindow.xib concept, which appears to be replaced by the following Xcode-inserted code in AppDelegate.m:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
self.viewController = [[ViewController alloc] initWithNibName:#"ViewController" bundle:nil];
self.window.rootViewController = self.viewController;
[self.window makeKeyAndVisible];
return YES;
}
I modified this method to generate a generic root view controller from which my ViewController class is presented, as shown in the code below:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
ViewController* myViewController = [[ViewController alloc] initWithNibName:#"ViewController" bundle:nil];
self.viewController = [[UIViewController alloc] init];
self.window.rootViewController = self.viewController;
[self.window makeKeyAndVisible];
[self.viewController presentModalViewController:myViewController animated:NO];
return YES;
}
Voila! This solved my problem. However, to me it feels like a change at a fundamental level, which I don't want to make at this point in my development. What I intended to be my root view controller is now a modal view. Does anyone have another solution to this issue?
Thanks in advance!
I had this same issue: an app which was meant to be in Landscape that assumed the ViewController was always in Portrait. I made tons of changes to every aspect of the project and info.plist, including giving the main UIWindow a root-view controller which was landscape. It still didn't work. I eventually undid all the changes and just added the two lines noted below to my app delegate:
- (void)applicationDidFinishLaunching:(UIApplication *)application
{
[_window addSubview:[_viewController view]];
glView = _viewController.glView;
// THIS FIXED ORIENTATION FOR ME IN IOS 6
_window.rootViewController = self.viewController;
[self.window makeKeyAndVisible];
// END
...my other setup code here...
}
Nothing else was necessary.
It appears that, for some reason, in iOS 6 the UIWindow root-view-controller setting is sometimes ignored in Interface Builder. I am sure my reasoning is wrong somewhere, but I thought this might well help prod someone in the direction of a fuller, more exhaustive answer.
In iOS 8, settings windows frame to the UIScreen is also necessary, as it won't get automatically updated.
self.window.frame = [UIScreen mainScreen].bounds;
I've set up a BOOL called isUsingiPad to detect when my user is using an iPad. I used this to do so:
UIDevice* userDevice = [UIDevice currentDevice];
if (userDevice.userInterfaceIdiom == UIUserInterfaceIdiomPad) {
isUsingiPad = YES;
}
When my application first starts, it checks to see if the device being used has gone through my registration. If it has then it sends the user to the main View Controller of my app. However... when a registered user (that is using an iPad) registers, closes the app, then re-opens it, they are sent to the iPhone nib instead of the iPad. I have 2 nibs for each view in my app. One for iPhone and one for iPad. There is a single View Controller controlling each set of 2. I have already put in place the code to handle whether it's an iPhone or an iPad. My question is this: What should I add to make sure that a user gets to the iPad nib every single time? Where do I add this? I can edit this question to include any code necessary. Thanks in advance.
Edit: Updated -(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions: method.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Override point for customization after application launch.
UIDevice* userDevice = [UIDevice currentDevice];
if (userDevice.userInterfaceIdiom == UIUserInterfaceIdiomPad) {
isUsingiPad = YES;
}
if (!isUsingiPad) {
self.viewController= [[PassportAmericaViewController alloc] initWithNibName:#"PassportAmericaViewController" bundle:nil];
} else {
self.viewController = [[PassportAmericaViewController alloc] initWithNibName:#"PassportAmericaViewController-iPad" bundle:nil];
}
self.window.rootViewController = self.viewController;
[self.window addSubview:navigationController.view];
[self.window makeKeyAndVisible];
return YES;
}
This is what Apple uses in the app templates to achieve this, it is implemented in your AppDelegates applicationDidFinishLaunchingWithOptions:
Now making sure that your user is returned to the correct screen every single time, depending on your setup you may want to initialize this in viewDidLoad or viewDidAppear.
- (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;
}
In order to dynamically load nibs for iPad/iPhone in universal applications you should use the following naming conventions:-
iPhone - MyNibName.xib
iPad - MyNibName~ipad.xib
Doing it this way you do not need to do any manual loading or if statements.