I have 3 storyboards for 3 different device screen size. I want to move from the main ViewController to the second ViewController when a button is pressed for the 3 storyboards. Here's the code:
In AppDelegate.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
if(UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone){
UIStoryboard *storyBoard;
CGSize result = [[UIScreen mainScreen] bounds].size;
CGFloat scale = [UIScreen mainScreen].scale;
result = CGSizeMake(result.width * scale, result.height * scale);
if(result.height == 1136){
storyBoard = [UIStoryboard storyboardWithName:#"Main_iPhone" bundle:nil];
UIViewController *initViewController = [storyBoard instantiateInitialViewController];
[self.window setRootViewController:initViewController];
}
else {
storyBoard = [UIStoryboard storyboardWithName:#"Main_iPhone4" bundle:nil];
UIViewController *initViewController = [storyBoard instantiateInitialViewController];
[self.window setRootViewController:initViewController];
}
}
return YES;
}
The code to move to second ViewController:
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main_iPhone/Main_iPhone4/Main_iPad" bundle: nil];
ArcadeView *svc = [storyboard instantiateViewControllerWithIdentifier:#"arcade"];
self.window.rootViewController = svc;
However, when i use the above code. XCode tells me
"Could not find a storyboard named
'Main_iPhone/Main_iPhone4/Main_iPad' in bundle NSBundle.
How do i fix this?
Because you don't have a storyboard with name #"Main_iPhone/Main_iPhone4/Main_iPad".
To make it work the way you want, do better in every storyboard make identical transitions and sign them the same identifier.
And for the transitions, use:
[self performSegueWithIdentifier:#"ShowMainMenu" sender:self]
But in general, I advise you to learn more about constraints. So it will be much easier
Related
I've had an iPhone only app, built for the most part with the Interface builder.
I have a storyboard for each screensize/device.
In the AppDelegate, it selects the correct storyboard and loads it.
I've since redesigned my app and now adding iPad compatibility.
I've added two new storyboards, fixed their size to "iPad Full Screen" and "iPad Pro Full Screen".
I've copied in the existing iPhone Storyboards and ticked the first board as "Is Initial View Controller".
I've also followed THIS POST and opened storyboards as source code and updated the target from default to iPad.
When I launch the app on an iPad, i just get a black screen with the following error:
Application windows are expected to have a root view controller at the end of application launch.
Why is this happening?
This is the only thing I've changed in my AppDelegate to select the correct Storyboard:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
UIViewController *initialViewController = nil;
CGSize result = [[UIScreen mainScreen] bounds].size;
if(UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone){
if(result.height == 480){
NSLog(#"iPhone 3.5 Inch");
UIStoryboard *i4SB = [UIStoryboard storyboardWithName:#"iPhone35" bundle:nil];
initialViewController = [i4SB instantiateInitialViewController];
}
if(result.height == 568){
NSLog(#"iPhone 4 Inch");
UIStoryboard *i5SB = [UIStoryboard storyboardWithName:#"iPhone4" bundle:nil];
initialViewController = [i5SB instantiateInitialViewController];
}
if(result.height == 667){
NSLog(#"iPhone 4.7 Inch");
UIStoryboard *i47SB = [UIStoryboard storyboardWithName:#"iPhone47" bundle:nil];
initialViewController = [i47SB instantiateInitialViewController];
}
if(result.height == 736){
NSLog(#"iPhone 5.5 Inch");
UIStoryboard *i55SB = [UIStoryboard storyboardWithName:#"iPhone55" bundle:nil];
initialViewController = [i55SB instantiateInitialViewController];
}
//added iPad compatibility
if(result.height == 1024){
NSLog(#"iPad Mini(2,3,4) or iPad Air(1,2) or iPad(3,4) or iPad Pro(9.7inch)");
UIStoryboard *iPadMiniSB = [UIStoryboard storyboardWithName:#"iPadFull" bundle:nil];
initialViewController = [iPadMiniSB instantiateInitialViewController];
}
if(result.height == 1366){
NSLog(#"iPad Pro(12.9 Inch)");
UIStoryboard *iPadProSB = [UIStoryboard storyboardWithName:#"iPadPro" bundle:nil];
initialViewController = [iPadProSB instantiateInitialViewController];
}
}
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
self.window.rootViewController = initialViewController;
[self.window makeKeyAndVisible];
return YES;
}
UPDATED / SOLUTION:
As Bharat Nakum mentioned below, you can remove the UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone condition.
Of course, you can also add an extra condition for iPad (which is what I did).
It now looks like this:
if(UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone){
//set iPhone device storyboards here
}
else if(UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad){
//set iPad device storyboards here
}
This is also confirmed as an answer here.
Please remove this condition.
if(UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone)
It is true only when device is iPhone.
So, your iPad storyboards are not initializing.
Hope this helps!
I had an app with two storyboards, one for the 4inch screen and one for the 3.5 inch screen. I had the following code in my "didfinishlaunchingwithoptions" to load the right storyboard at launch...
if(UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone){
UIStoryboard *storyBoard;
CGSize result = [[UIScreen mainScreen] bounds].size;
CGFloat scale = [UIScreen mainScreen].scale;
result = CGSizeMake(result.width * scale, result.height * scale);
if(result.height == 960){
storyBoard = [UIStoryboard storyboardWithName:#"3inchstoryboard" bundle:nil];
UIViewController *initViewController = [storyBoard instantiateInitialViewController];
[self.window setRootViewController:initViewController];
}
}
With the release of Xcode 6 and iOS 8, this no longer works how it should, it just loads up the storyboard for the 4inch every time no matter what device, do you know how I can get this to work on iOS 8 in Xcode 6?
you can have these conditions, one for iPhone 4,4s (960) and the other for 5,5s,6,6plus (1136) the last for ipads
if(UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone){
UIStoryboard *storyBoard;
CGSize result = [[UIScreen mainScreen] bounds].size;
CGFloat scale = [UIScreen mainScreen].scale;
result = CGSizeMake(result.width * scale, result.height * scale);
if(result.height == 960){ //storyboard for 4,4s
storyBoard = [UIStoryboard storyboardWithName:#"storyboard4" bundle:nil];
UIViewController *initViewController = [storyBoard instantiateInitialViewController];
[self.window setRootViewController:initViewController];
}
if(result.height == 1136){ //storyboard for 5,5s,6,6plus
storyBoard = [UIStoryboard storyboardWithName:#"storyboard5" bundle:nil];
UIViewController *initViewController = [storyBoard instantiateInitialViewController];
[self.window setRootViewController:initViewController];
}
}else { //storyboard for ipads
storyBoard = [UIStoryboard storyboardWithName:#"storyboardipad" bundle:nil];
UIViewController *initViewController = [storyBoard instantiateInitialViewController];
[self.window setRootViewController:initViewController];
}
I'm implementing FPPopover into my application, it was working alright until I added some code to the app delegate to manage and display the correct storyboard depending on the device throughout the app. The code I added is as follows...
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{
UIStoryboard *storyboard = [self getStoryboard];
UIViewController *initViewController = [storyboard instantiateViewControllerWithIdentifier:#"Init"];
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
self.window.rootViewController = initViewController;
[self.window makeKeyAndVisible];
sleep(3);
return YES;}
-(UIStoryboard*) getStoryboard {
UIStoryboard *storyBoard = nil;
if ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPad) {
storyBoard = [UIStoryboard storyboardWithName:#"MainStoryboard_iPad" bundle:nil];
}else{
if ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPhone){
// The iOS device = iPhone or iPod Touch
CGSize iOSDeviceScreenSize = [[UIScreen mainScreen] bounds].size;
if (iOSDeviceScreenSize.height == 480){
// iPhone 3/4x
storyBoard = [UIStoryboard storyboardWithName:#"MainStoryboard" bundle:nil];
}else if (iOSDeviceScreenSize.height == 568){
// iPhone 5 etc
storyBoard = [UIStoryboard storyboardWithName:#"Storyboard_iPhone_5" bundle:nil];
}
}
}
return storyBoard;}
If I delete all this code from my App delegate the popover works perfectly... But if I add it it doesn't work... I have no idea what is going on.
Can anyone help?
You don't need of this code..go in the project's general tab and set your storyboard for iPhone and iPad here:
In the storyboard you can select the inital view controller..
So you can delete all your code for storyboard and initial viewController
This is the code that i use in my appDelegate :) :
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
return YES;
}
I decided to use different storyboards for ios6 and and ios7 and so I need to instantiate storyboards in code. I have this method in the app delegate´s - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
but nothing happens, it always just instantiate the storyboard named iPadStoryboardwhen run on the iPad simulator, I have deleted the Main interface´s from the info.plist. Any idea what´s happening here?
- (void)loadStoryboards
{
CGSize iOSDeviceScreenSize = [[UIScreen mainScreen] bounds].size;
UIStoryboard *mainStoryboard = nil;
if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(#"6.0"))
NSLog(#"1");
if (iOSDeviceScreenSize.height == 480)
{
mainStoryboard = [UIStoryboard storyboardWithName:#"MainStoryboard_iPhone-ios5" bundle:nil];
} else {
NSLog(#"loading iPad storyboard");
mainStoryboard = [UIStoryboard storyboardWithName:#"iPadStoryboardOS6" bundle:nil];
}
if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(#"7.0"))
NSLog(#"2");
if (iOSDeviceScreenSize.height == 480)
{
mainStoryboard = [UIStoryboard storyboardWithName:#"MainStoryboard_iPhone" bundle:nil];
} else {
mainStoryboard = [UIStoryboard storyboardWithName:#"iPadStoryboard" bundle:nil];
}
self.initialViewController = [mainStoryboard instantiateInitialViewController];
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
self.window.rootViewController = self.initialViewController;
[self.window makeKeyAndVisible];
}
Be careful how you check for iPad. 480px screen height doesn't cover iPhone5. Use:
if([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad)
I am using this code to adapt my storyboard depending on device (iphone 5 or less):
if([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone){
if(UIScreenOverscanCompensationScale==1136/640){
//move to your iphone5 storyboard
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"iphone5 storyboard" bundle:[NSBundle mainBundle]];
}
else{
//move to your iphone4s storyboard
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"MainStoryboard_iPhone" bundle:[NSBundle mainBundle]];
}}
The code doesn't work even if I just place:
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"iphone5 storyboard" bundle:[NSBundle mainBundle]];
...it still loads iphone normal.
I put it under:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
in app delegate. Is this right?? In the app settings I chose the original iphone storyboard
The problem is that:
UIScreenOverscanCompensationScale==1136/640
will never be true.
Check what UIScreenOverscanCompensationScale is doing and return a BOOL.
Is MainStoryboard still specified under target summary? I believe that this will be where the app looks first.
I managed to solve it in this way:
if([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone){
if([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone && [UIScreen mainScreen].bounds.size.height == 568.0){
//move to your iphone5 storyboard
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"iphone5 storyboard" bundle:[NSBundle mainBundle]];
UIViewController *vc =[storyboard instantiateInitialViewController];
// Set root view controller and make windows visible
self.window.rootViewController = vc;
[self.window makeKeyAndVisible];
}
else{
//move to your iphone4s storyboard
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"MainStoryboard_iPhone" bundle:[NSBundle mainBundle]];
UIViewController *vc =[storyboard instantiateInitialViewController];
// Set root view controller and make windows visible
self.window.rootViewController = vc;
[self.window makeKeyAndVisible];
}}