I have made a pro and lite version app using different target from an project. These two apps use different storyboard and info.plist file.
I want to make in app purchase button in lite version app for operating like pro version app. For do that, I need to change the storyboard file that lite version uses to pro version's storyboard file when users buy in app purchase feature.
The storyboard file name used is stored at 'main storyboard file base name' in xxx-info.plist file. So, can I change the storyboard file base name when users do something. I don't know it's possible or not.
How can I get this?
Thank you.
You can set it dynamically at startup:
// set storyBoardName according to upgrade status
UIStoryboard *storyBoard =
[UIStoryboard storyboardWithName:storyBoardName bundle:nil];
UIViewController *initViewController =
[storyBoard instantiateInitialViewController];
[self.window setRootViewController:initViewController];
So I guess it is OK to start up the app again after upgrade.
Yes, in your AppDelegate application:didFinishLaunchingWithOptions:launchOptions method you can get the storyboard name from your plist, and then load the storyboard based on this setting. Or, you could store the storyboard name in UserDefaults instead, and update that setting after the user has paid for the pro version.
Or, you can use UserDefaults to store just whether the user has upgraded or not, and keep the storyboard names as constants in appdelegate:
#define kStoryboardLite #"LiteStoryboard.storyboard"
#define kStoryboardPro #"ProStoryboard.storyboard"
...
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
NSString *storyboardName;
NSString *userType = [[NSUserDefaults standardUserDefaults] objectForKey:#"userType"];
if ([userType isEqualToString:#"pro"]) {
storyboardName = kStoryboardPro;
} else {
storyboardName = kStoryboardLite;
}
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:storyboardName bundle:nil];
UIViewController *initialViewController = [storyboard instantiateInitialViewController];
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
self.window.rootViewController = initialViewController;
[self.window makeKeyAndVisible];
}
If you use this approach, you would have to ask your user to restart the app to load the other storyboard.
Related
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:
I am unable to set a specific Main interface for iPad, even though my app is universal. Xcode used to have separate tabs for the Deployment Info on iPhone and iPad but now they are they same. However my game is radically different on iPhone and iPad and I need to set separate storyboards for each interface.
Someone please help if you know the solution.
you could set the value in the Deployment Info -> Main Interface to an empty string and implement a custom logic in your AppDelegate:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
UIStoryboard *initialStoryboard;
if ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPhone) {
initialStoryboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
} else {
initialStoryboard = [UIStoryboard storyboardWithName:#"Main_iPad" bundle:nil];
}
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
self.window.rootViewController = [initialStoryboard instantiateInitialViewController];
[self.window makeKeyAndVisible];
return YES;
}
You need to use size classes for this. To select the correct size class, open your storyboard file, then click on this icon towards the bottom of the screen.
Clicking wAny hAny will allow you to change the size class type and set specific constraints for the different device types. You can read more information about size classes here
We have an error with our iOS game. The gameover screen (containing the score) doesn't come up after losing the game, as it just hangs up. Can anyone suggest what could be the problem and how can we fix this?
We are currently testing and we are not sure if this is the case because of the code or the test settings? But so far the Xcode doesn't show any errors.
Thanks for your help.
Open a view from a normal class:
UIStoryboard *storyBoard = [UIStoryboard storyboardWithName:storyBoardName bundle:nil];
UIViewController *viewController = [storyBoard instantiateViewControllerWithIdentifier:StoryboardID];
[self presentViewController:viewController animated:NO completion:nil];
Edit these strings to:
storyBoardName = The name of your storyboard.
storyBoardID = The StoryBoardID of your ViewController.
Open a view from the AppDelegate
UIStoryboard *storyBoard = [UIStoryboard storyboardWithName:storyBoardName bundle:nil];
UIViewController *viewController = [storyBoard instantiateViewControllerWithIdentifier:storyBoardID];
self.window = [[UIWindow alloc] initWithFrame:UIScreen.mainScreen.bounds];
self.window.rootViewController = viewController;
[self.window makeKeyAndVisible];
Edit these strings to:
storyBoardName = The name of your storyboard.
storyBoardID = The StoryBoardID of your ViewController.
Other information
How to get the storyBoardName?
If your StoryBoard is called Main.storyboard Main is the title.
If your StoryBoard is called MyName.storyboard MyName is the title
How to set a StoryBoardID?
Select your ViewController. Your View must now be highlighted blue. Go to the identity inspector and under identity you'll find StoryBoardID. Set it to whatever you like.
If it still doesn't work when you use this code you have put in the wrong variables, or there's an unknown 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.
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];