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;
}
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 need to choose which MainViewController.h to load depending on the iPhone model that the app is running on. Using the code below, I distinguish between iPhone 4/4S and 5/5S/5C. Because of the auto layout, I will need to create two mainViewController.hs and then choose depending on the model of the phone. How do I do this? This is the code I have:
#define IS_IPHONE_5 ( fabs( ( double )[ [ UIScreen mainScreen ] bounds ].size.height - ( double )568 ) < DBL_EPSILON )
- (void)viewDidLoad
{
[super viewDidLoad];
if (IS_IPHONE_5) {
NSLog(#"Iphone 5");
} else {
NSLog(#"Iphone4");
}
}
So please tell me how to chose MainViewController.h.
AppDelegate.m:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
[application registerForRemoteNotificationTypes:UIRemoteNotificationTypeBadge|
UIRemoteNotificationTypeAlert|
UIRemoteNotificationTypeSound];
// Override point for customization after application launch.
return YES;
UIStoryboard *storyboard;
CGSize screenSize = [[UIScreen mainScreen] bounds].size;
if (screenSize.height == 568) {
// iPhone 5
storyboard = [UIStoryboard storyboardWithName:#"MainStoryboard_iPhone5" bundle:nil];
} else {
// iPhone 4
storyboard = [UIStoryboard storyboardWithName:#"MainStoryboard_iPhone4" bundle:nil];
}
UIViewController *initialViewController = [storyboard instantiateInitialViewController];
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
self.window.rootViewController = initialViewController;
[self.window makeKeyAndVisible];
}
To specify which storyboard to load, do so in your AppDelegate's application:didFinishLaunchingWithOptions: method.
Load the storyboard that corresponds to the screen size using its storyboard name, ex:
UIStoryboard *storyboard;
CGSize screenSize = [[UIScreen mainScreen] bounds].size;
if (screenSize.height == 568) {
// iPhone 5, i.e. 568 pixels high
storyboard = [UIStoryboard storyboardWithName:#"MainStoryboard_iPhone5" bundle:nil];
} else {
// earlier model iPhones, i.e. 480 pixels high
storyboard = [UIStoryboard storyboardWithName:#"MainStoryboard_iPhone4" bundle:nil];
}
UIViewController *initialViewController = [storyboard instantiateInitialViewController];
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
self.window.rootViewController = initialViewController;
[self.window makeKeyAndVisible];
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;
}
Just as an app utilizes different storyboards for iPad and iPhone, I would like my app to use a different storyboard for the iPhone 5. Since there is no option in the Info.plist to select default storyboard for iPhone 5, how would I programmatically call the storyboard?
I do not want to use AutoLayout for this app unless it is absolutely the last resort. I understand how to detect if a user is using an iPhone 5 or other device with the same screen size. I just need to know how to set the default storyboard without the plist.
I was looking for the same answer couple of weeks ago here's my solution hope helps..
-(void)initializeStoryBoardBasedOnScreenSize {
if ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPhone)
{ // The iOS device = iPhone or iPod Touch
CGSize iOSDeviceScreenSize = [[UIScreen mainScreen] bounds].size;
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
UIViewController *initialViewController = [iPhone35Storyboard 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];
}
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
UIViewController *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;
}
}
Call this method under AppDelegate ddiFinishLaunchingWithOptions: method
And also don't forget the name your storyboards properly
Hope helps...
This worked for me - slight refinement with wrapping getting the storyboard in a function
-(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_iPhone_4" bundle:nil];
}else if (iOSDeviceScreenSize.height == 568){
// iPhone 5 etc
storyBoard = [UIStoryboard storyboardWithName:#"MainStoryboard_iPhone_5" bundle:nil];
}
}
}
ASSERT(storyBoard);
return storyBoard;
}
UIStoryboard* mainStoryBoard = [self getStoryboard];
self.initialViewController = [mainStoryBoard instantiateInitialViewController];
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
self.window.rootViewController = self.initialViewController;
[self.window makeKeyAndVisible];