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];
}
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 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
I want to call UIStoryboard for three diffrent device (iphone4s,iphone5 and ipad). I have newly added for iphone4s device. I have the following Storyboard
Main_iPhone
Main_iPhone4(newly added)
Main_iPad
Please check my current source. Its working working with iphone5.
AVCamViewController *vc = [[UIStoryboard
storyboardWithName:#"Main_iPhone" bundle:NULL]
instantiateViewControllerWithIdentifier:#"rootController"];
vc.modalPresentationStyle = UIModalPresentationFormSheet;
vc.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
[self.viewControllerCam presentViewController:vc animated:YES completion:nil];
I need to change like below and i was run with iphone4s device. but still im seeing "Main_iPhone" storyboard. PLease help me how to switch Main_iPhone4 when i was run in iphone4s device.
UIStoryboard *storyboard = nil;
if ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPhone)
{
CGSize iOSDeviceScreenSize = [[UIScreen mainScreen] bounds].size;
if (iOSDeviceScreenSize.height == 480)
{
storyboard = [UIStoryboard storyboardWithName:#"Main_iPhone4" bundle:nil];
}
if (iOSDeviceScreenSize.height == 568)
{
storyboard = [UIStoryboard storyboardWithName:#"Main_iPhone" bundle:nil];
}
}
else if ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPad)
{
storyboard = [UIStoryboard storyboardWithName:#"Main_iPad" bundle:nil];
}
AVCamViewController *vc = [storyboard instantiateInitialViewController];
vc.view.backgroundColor = [UIColor clearColor];
vc.modalPresentationStyle = UIModalPresentationFormSheet;
vc.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
[self.viewControllerCam presentViewController:vc animated:YES completion:nil];
Your code seems fine and it should work according to that.
But this is not the right way to manage separate storyboard for iPhone 4s & iPhone 5/5s. Instead you can manage using single storyboard for both and arrange the layout using auto-layout, I'm sure it will reduce your lot of work.
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 the following code in my AppDelegate.m to detect which device the user is using:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
if(UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone)
{
CGSize result = [[UIScreen mainScreen] bounds].size;
if(result.height == 480)
{
NSLog(#"iPhone 3,5 Inch");
[UIStoryboard storyboardWithName:#"MainStoryboard_iPhone" bundle:nil];
}
if(result.height == 568)
{
NSLog(#"iPhone 4 Inch");
[UIStoryboard storyboardWithName:#"iPhone5-storyboard" bundle:nil];
}
}
return YES;
}
But when I build the App the NSLog is shown, but no Storyboard is coming up...
The Main Storyboard field in the Deployment info is empty so that the code decided what to load...
Can you help me?
Here is a way I now found on a other post:
if ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPhone)
{ // The iOS device = iPhone or iPod Touch
CGSize iOSDeviceScreenSize = [[UIScreen mainScreen] bounds].size;
UIViewController *initialViewController = nil;
if (iOSDeviceScreenSize.height == 480)
{ // iPhone 3GS, 4, and 4S and iPod Touch 3rd and 4th generation: 3.5 inch screen (diagonally measured)
// Instantiate a new storyboard object using the storyboard file named Storyboard_iPhone35
UIStoryboard *iPhone35Storyboard = [UIStoryboard storyboardWithName:#"Storyboard_iPhone35" bundle:nil];
// Instantiate the initial view controller object from the storyboard
initialViewController = [iPhone35Storyboard instantiateInitialViewController];
}
if (iOSDeviceScreenSize.height == 568)
{ // iPhone 5 and iPod Touch 5th generation: 4 inch screen (diagonally measured)
// Instantiate a new storyboard object using the storyboard file named Storyboard_iPhone4
UIStoryboard *iPhone4Storyboard = [UIStoryboard storyboardWithName:#"Storyboard_iPhone4" bundle:nil];
// Instantiate the initial view controller object from the storyboard
initialViewController = [iPhone4Storyboard instantiateInitialViewController];
}
// Instantiate a UIWindow object and initialize it with the screen size of the iOS device
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Set the initial view controller to be the root view controller of the window object
self.window.rootViewController = initialViewController;
// Set the window object to be the key window and show it
[self.window makeKeyAndVisible];
} else if ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPad)
{ // The iOS device = iPad
UISplitViewController *splitViewController = (UISplitViewController *)self.window.rootViewController;
UINavigationController *navigationController = [splitViewController.viewControllers lastObject];
splitViewController.delegate = (id)navigationController.topViewController;
}