How to call different Storyboards in iOS? - ios

I am using two storyboard first one for iphone Main.storyboard and second one is Main_iPad.storyboard and i wants to call separately for iPad and iPhone i am using this code:
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main_iPad" bundle:nil];
EABaseRootVC *loginController = [storyboard instantiateViewControllerWithIdentifier:#"root2"];
UINavigationController *navController=[[UINavigationController alloc]initWithRootViewController:loginController];
self.window.rootViewController=navController;
}
else
{
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
EABaseRootVC *loginController = [storyboard instantiateViewControllerWithIdentifier:#"root"];
UINavigationController *navController=[[UINavigationController alloc]initWithRootViewController:loginController];
self.window.rootViewController=navController;
}
But its always shows iPhone assets for Main.storyboard.
i am already follow this Different storyboards for iPhone and iPad in xcode 6
if you have any other idea so please suggest me.
what i am doing wrong?

To identify Apple devices specifically whether it is iPhone or iPad use below code:
if(UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad){
// code for iPad
}else{
// code for iPhone
}
And must add these two keys inside your project's .plist file.
Main storyboard file base name (iPad)
Main storyboard file base name (iPhone)
See image:

Related

UISplitViewController on universal app with Storyboard

I'm want to make an app that uses a UISplitViewControler on the iPad (as far as I understand it's only available on the iPad) but I want the app to be universal.
The setup is like this:
I have a UITableView (as a master view) and when I select a row it should display a detail view of that cell. I am using a Storyboard and I can't figure out how to implement the split view only for the iPad.
What would be the easiest way to achieve that? Thanks.
You don't need two storyboards to do this.You can use them both in a single storyboard.For iphone ,we normally use a class SWRevealViewController(if you are new to iOS coding ..:)) for side menu and splitviewcontroller for ipad.We can also use SWRevealViewController for ipad as well.It depends on your requirement.
For universal apps,create viewcontrollers using size Classes(usually we use any height any width for universal apps ).
change these size classes and create different viewcontrollers for ipad and iphones as required.In most cases any height any width will do the job.
After creating the viewcontrollers,in the appdelegate ,using the instantiateViewcontrollerWithIdentifier method, load the required viewcontroller.
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
// The device is an iPad running ios 3.2 or later.
}
else {
// The device is an iPhone or iPod touch.
}
For ipad load the splitviewcontroller. and swrevealviewcontroller for iPhone.
This is the core basics.If you need any more information,let me know.
EDIT
Have you seen an arrowmark ath the initial VC(viewcontroller) in the storyboard?This vc is loaded first after the launch screen.In my app,I have a home screen which is common to both iphone and ipad(using size classes as mentioned above).So I can set this vc as the initial VC.In this case I don't have to do anything in the appdelegate.But if I have a different home screen for ipad,then I can make a condition check in the appdelegate didFinishLaunchingWithOptions
You can load the First screen like this.You should follow through splitVC tutorilal and swrevealcontroller tutorial to set the side menu.You should load the SWrevealVC or splitViewcontroller only if the first screen contains the side menu.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad)
{
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
UISplitViewController *split = [storyboard instantiateViewControllerWithIdentifier:#"SplitViewController"];
[AppDelegate setRootController:split storyboard:storyboard actiontype:0];
}
else if(UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone)
{
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
UIViewController *split = [storyboard instantiateViewControllerWithIdentifier:#"SWrevealVC"];
[AppDelegate setRootController:split storyboard:storyboard actiontype:-1];
}
return YES;
}
+(void)setRootController:(UIViewController*)controller
storyboard:(UIStoryboard*)storyboard actiontype:(int) actiontype;
{
if ( UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad && actiontype == 0)
{
UISplitViewController *splitViewController = (UISplitViewController *)controller;
//splitViewController.presentsWithGesture = false;
UINavigationController *masterNavigationController = [splitViewController.viewControllers objectAtIndex:0];
SideMenuViewController *controller = (SideMenuViewController *)masterNavigationController.topViewController;
controller.splitViewController = splitViewController;
splitViewController.delegate = (id)controller;
}
AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
[UIView
transitionWithView:appDelegate.window
duration:0.5
options:UIViewAnimationOptionAllowAnimatedContent
animations:^(void) {
BOOL oldState = [UIView areAnimationsEnabled];
[UIView setAnimationsEnabled:NO];
appDelegate.window.rootViewController = controller;
[UIView setAnimationsEnabled:oldState];
}
completion:nil];
}
The code may look lengthy,but take it simple.You can only understand the logic if u do things.

"Application windows are expected..." error when loading storyboard for Ipad

I'm loading different storyboards for Iphone and Ipad and the Iphone's storyboards load good but when I start the Ipad Simulator I got the "Application windows are expected..." error.
this is the code in AppDelegate:
#implementation AppDelegate
- (UIStoryboard *)grabStoryboard {
UIStoryboard *storyboard;
// detect the height of our screen
int height = [UIScreen mainScreen].bounds.size.height;
if (height == 480) {
storyboard = [UIStoryboard storyboardWithName:#"Storyboard_Iphone3" bundle:nil];
// NSLog(#"Device has a 3.5inch Display.");
}
if (height >= 1024 && height <= 2048 ) {
storyboard = [UIStoryboard storyboardWithName:#"Storyboard_Ipad" bundle:nil];
NSLog(#"Device has a 4inch Display.");
}
else {
storyboard = [UIStoryboard storyboardWithName:#"Storyboard_Iphone4Up" bundle:nil];
// NSLog(#"Device has a 4inch Display.");
}
return storyboard;
}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
UIStoryboard *storyboard = [self grabStoryboard];
// show the storyboard
self.window.rootViewController = [storyboard instantiateInitialViewController];
[self.window makeKeyAndVisible];
return YES;
}
In the console I see the NSLog message but the storyboard doesn't load and the "Application windows..." error appears.
I'm using some Scroll Views and some elements but i thinkg those are not the problem because there is an option for them "Adjust Scroll View Insets".
I uploaded some screen shots to show more about my project. Thanks for your time.
I figured it out. When you copy all stuff from the Iphone storyboard to the Ipad one the Initial View Controller checkbox is unchecked. Just check it and all will be good (:

Using multiple Storyboards in Xcode

I have created 5 extra Storyboards and I have deleted the main storyboard. This is because I would like to have 5 separate storyboards for the iPhone and iPad to match 5 different screen sizes. So far I have one for the iPhone 3.5 inch, one for the iPhone 4 inch, one for the iPhone 4.7 inch, one for the iPhone 5.5 inch and one for the iPad. I have put the code bellow in to link it all up and make it work. However, it doesn't work when you try and build the project. There is no errors but lets say I go into the iPhone 3.5 inch storyboard and I add a UIViewController and a Button or label, then when you build the project it goes to your launch screen and then it doesn't do anything from there. I have put the starting arrow in at the UIViewController but I cannot get anything to come up apart from the launch screen. I have tried this on all the storyboards and their simulators. I am wondering if I have missed something out in the code but I am not sure.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
UIStoryboard *storyboard = nil;
if ([[UIDevice currentDevice] userInterfaceIdiom] ==UIUserInterfaceIdiomPad) {
storyboard = [UIStoryboard storyboardWithName:#"Storyboard_iPad" bundle:nil];//iPad
} else {
CGSize screenSize = [[UIScreen mainScreen] bounds].size;
if (screenSize.height == 480){
storyboard = [UIStoryboard storyboardWithName:#"Storyboard_iPhone4S" bundle:nil];//iPhone 3.5inch
} else
if (screenSize.height == 568){
storyboard = [UIStoryboard storyboardWithName:#"Storyboard_iPhone5/5C/5S" bundle:nil];//iPhone 4inch
}
else
{ if (screenSize.height == 667){
storyboard = [UIStoryboard storyboardWithName:#"Storyboard_iPhone6" bundle:nil];//iPhone 4.7inch
} else
if (screenSize.height == 736){
storyboard = [UIStoryboard storyboardWithName:#"Storyboard_iPhone6Plus" bundle:nil];//iPhone 5.5inch
} else
//default storyboard
storyboard = [UIStoryboard storyboardWithName:#"Main.Storyboard" bundle:nil];
}
}
self.window.rootViewController = [storyboard instantiateInitialViewController];
[self.window makeKeyAndVisible];
return YES;
}
Find your info.plist file in your project and remove the line called "Main storyboard file base name".
Also, you forgot to create the window (credits to rdelmar).
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
I strongly advise you to look into Auto Layout and Size Classes. Using these two, you can support all screen sizes within one single Storyboard. It's a bit hard to get in the beginning, but it'll definitely be worth it in the long run.
There's a video about this from the most recent WWDC called Building Adaptive Apps with UIKit.

Adding a second storyboard causes "could not find storyboard" error

I started by building 2 versions of my app, on for 3.5 inch screens and one for 4 inch with only the storyboard being different. I brought the 3.5 storyboard into the 4 inch project and used the following code in my appDelegate.m to have the program run the appropriate storyboard.
UIViewController *vc;
if([[UIDevice currentDevice]userInterfaceIdiom]==UIUserInterfaceIdiomPhone)
{
if ([[UIScreen mainScreen] bounds].size.height == 568.0f)
{
NSLog(#"IPHONE IS WORKING");
UIStoryboard *storybord = [UIStoryboard storyboardWithName:#"Main.storyboard" bundle:nil];
vc = [storybord instantiateInitialViewController];
}
else
{
UIStoryboard *storybord = [UIStoryboard storyboardWithName:#"MainFour.storyboard" bundle:nil];
vc = [storybord instantiateInitialViewController];
}
}
else
{
UIStoryboard *storybord = [UIStoryboard storyboardWithName:#"iPad" bundle:nil];
vc = [storybord instantiateInitialViewController];
}
[_window setRootViewController:vc];
[_window makeKeyAndVisible];
When I use this, I get the error:
"Could not find a storyboard named 'Main.storyboard' in bundle
NSBundle"
The error happens even if I try and use the storyboard that was not imported, the one that runs if the above code is missing. So I am assuming that the error lies in the name of the storyboard. In the project navigator, the storyboard is named "Main.storyboard" but calling that name does not find it. What am I doing wrong? Thanks.
Drop the .storyboard extension from the name you specify.
From the reference:
storyboardWithName:bundle:
Creates and returns a storyboard object for the specified storyboard resource file.
+ (UIStoryboard *)storyboardWithName:(NSString *)name
bundle:(NSBundle *)storyboardBundleOrNil
Parameters
name The name of the storyboard resource file without the filename extension. This method raises an exception if this parameter is nil.

How to load multiple storyboard files depending on iOS version? (5 and 6)

I have a tab bar controller app that I am trying to make compatible for iOS 6 and iOS 5.
For iOS 6, I use auto layout.
But when trying to run on iOS 5, I get an error due to it not recognizing NSLayoutConstraints.
From what I can tell, I am required to use a different storyboard without auto layout enabled. I have copied my storyboard into a new one, but don't know how to set which storyboard to use in the app delegate.
Whats the code to do this?
In your app delegate, you should find code like this:
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"MyStoryboard" bundle:nil];
self.window.rootViewController = [storyboard instantiateInitialViewController];
[self.window makeKeyAndVisible];
This is where you can add some code to choose among the several storyboards that you have depending on the version of iOS:
UIStoryboard *storyboard;
NSString *currSysVer = [[UIDevice currentDevice] systemVersion];
if (...) {
storyboard = [UIStoryboard storyboardWithName:#"MyStoryboard-v5" bundle:nil];
} else {
storyboard = [UIStoryboard storyboardWithName:#"MyStoryboard-v6" bundle:nil];
}
self.window.rootViewController = [storyboard instantiateInitialViewController];
[self.window makeKeyAndVisible];

Resources