in my project i have different Storyboard files to support different iPhones, i have this code in my appDelegate:
if (window.frame.size.height == 568){
UIStoryboard *storyBoard = [UIStoryboard storyboardWithName:kMain5Name bundle:[NSBundle mainBundle]];
id rootViewController = [storyBoard instantiateInitialViewController];
[window setRootViewController:rootViewController];
} else if (window.frame.size.height == 480){
UIStoryboard *storyBoard = [UIStoryboard storyboardWithName:kMain5Name bundle:[NSBundle mainBundle]];
id rootViewController = [storyBoard instantiateInitialViewController];
[window setRootViewController:rootViewController];
} else if (window.frame.size.height == 667){
UIStoryboard *storyBoard = [UIStoryboard storyboardWithName:kMain6Name bundle:[NSBundle mainBundle]];
id rootViewController = [storyBoard instantiateInitialViewController];
[window setRootViewController:rootViewController];
} else if (window.frame.size.height == 736){
UIStoryboard *storyBoard = [UIStoryboard storyboardWithName:kMain6plusName bundle:[NSBundle mainBundle]];
id rootViewController = [storyBoard instantiateInitialViewController];
[window setRootViewController:rootViewController];
}
every time i compile and run the app crashes saying it could not find storyboard file in NSBundle, i tied commenting out the above code and it worked again. is there something wrong with my code?
Here is an excerpt from UIStoryboard Class reference
Parameters
name
The name of the storyboard resource file without the filename extension. This method raises an exception if this parameter is nil.
I made the relevant part bold. In case you are not a native speaker, it means do not add the extension into the parameter. But you did exactly that in your macro.
You really should read the documentation before trying to find some more esoteric cause for any problems in code.
Related
I'm trying to load a view controller that's in a .storyboard in a pod. I'm using the following which normally works:
UIStoryboard *storyboard = [UIStoryboard
storyboardWithName:#"StoryboardName" bundle:nil];
NewViewController *newView = [storyboard instantiateViewControllerWithIdentifier:#"NewViewController"];
[self.navigationController pushViewController:newView animated:YES];
What do I need to change it to so I can load from a pod?
You should load it with it's bundle identifier
NSBundle* bun = [NSBundle bundleWithIdentifier:"id"]
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"StoryboardName" bundle:bun];
I have tried many code in my didReceiveRemoteNotification function in appdelegate.m
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
//Code
}
but didn`t work as expected.
With this code, doesn`t navigate to my profile view controller after I click the notification:
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
ProfileViewController *controller = [storyboard instantiateViewControllerWithIdentifier:#"profileIdentifier"];
controller.userID = #"123";
controller.userName = #"calvinsug";
UINavigationController *navigationController = (UINavigationController *)self.window.rootViewController;
[navigationController pushViewController:controller animated:YES];
I have tried this also but didn`t navigate to the profile controller
[self.window.rootViewController presentViewController:controller animated:YES completion:NULL];
Finally, I try this code, but it is weird because it doesn't have back button (I think the cause is the profile controller become the initial view).
self.window = [[UIWindow alloc]
initWithFrame:UIScreen.mainScreen.bounds];
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
ProfileViewController *controller = [storyboard instantiateViewControllerWithIdentifier:#"profileIdentifier"];
controller.userID = #"123";
controller.userName = #"calvinsug";
self.window.rootViewController = controller;
[self.window makeKeyAndVisible];
Any one have solution?
edit:
I think we can not set our target View controller to become a Root View Controller, because when we click notifications in other apps, we go to main screen first, then go to the specific view controller immediately
Try this:
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
ProfileViewController *controller = [storyboard instantiateViewControllerWithIdentifier:#"profileIdentifier"];
controller.userID = #"123";
controller.userName = #"calvinsug";
UINavigationController *navController = [[UINavigationController alloc]initWithRootViewController:controller];
self.window.rootViewController = navController;
`
I have divided my project into two storyboards:
Main.storyboard - For authenticated user. Also this is the default storyboard.
Login.storyboard - For non-authenticated user.
App delegate file:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
if(user is authenticated)
{
[self presentLoginScreen:YES];
return YES;
}
Login Screen in app delegate file:
-(void)presentLoginScreen:(BOOL)animated{
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Login" bundle:[NSBundle mainBundle]];
UIViewController *vc =[storyboard instantiateInitialViewController];
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
self.window.rootViewController = vc;
}
On logout, login Screen is presented. I defined this in app delegate file:
-(void)logOut{
//clear data
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Login" bundle:[NSBundle mainBundle]];
UIViewController *vc =[storyboard instantiateInitialViewController];
self.window.rootViewController = vc;
//Show login Screen
[self presentLoginScreen:NO];
}
From viewcontroller of MainStoryBoard(letsay mainstoryboardVc.m), logOut is called as:
-(void)didTouchLogOut{
NSLog(#"GoodBye");
AppDelegate *appDelegateTemp = [[UIApplication sharedApplication]delegate];
[appDelegateTemp logOut];
}
This is causing a lot of issue:
Firstly, when I log out, and move to login screen, I can still see mainstoryboardVc.m in the background which looks very clumsy.
I log out, re-log in and again trying to log out, I see following message:
Presenting view controllers on detached view controllers is discouraged
and login screen is not presented.
I tried many answers on the web on view controller presentations between two storyboards without keeping history, nothing seems to work...
To swap out UIViewControllers there are a few other methods that need to be called when transitioning the root view controller:
Objective-c:
- (void)setRootViewController:(UIViewController *) newRootViewController {
UIViewController* currentViewController = self.window.rootViewController;
if (newRootViewController != currentViewController) {
[currentViewController willMoveToParentViewController:nil];
[currentViewController.view removeFromSuperview];
[currentViewController removeFromParentViewController];
self.window.rootViewController = newRootViewController;
}
}
Swift:
func setRootViewController(newRootViewController: UIViewController) {
if let currentViewController = self.window?.rootViewController {
if currentViewController != newRootViewController {
currentViewController.willMoveToParentViewController(nil)
currentViewController.view.removeFromSuperview()
currentViewController.removeFromParentViewController()
self.window?.rootViewController = currentViewController
}
}
}
Two UIViewController objects are duplicated because you set self.window.rootViewController for both of them. Try that;
Login
-(void)presentLoginScreen:(BOOL)animated{
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Login" bundle:[NSBundle mainBundle]];
UIViewController *vc =[storyboard instantiateInitialViewController];
self.window.rootViewController = vc;
[self.window makeKeyAndVisible];
}
Logout
-(void)logOut{
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Login" bundle:[NSBundle mainBundle]];
UIViewController *vc =[storyboard instantiateInitialViewController];
[self presentViewController:vc animated:YES completion:nil];
}
How can I access storyboard as well as it's UIViewControllers inside the appDelegate.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
return YES;
}
Try this :
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
UIViewController *uvc = [storyboard instantiateViewControllerWithIdentifier:#"Details"];
[self.window.rootViewController presentViewController:uvc animated:YES completion:nil];
For the case your UIViewController is named MyViewController and its storyboard has name MyViewController.storyboard, the code you've requested will look like this:
// load storybord with name MyViewController.storyboard
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"MyViewController" bundle:nil];
// get an instance of root view controller for the storyboard
MyViewController *viewController = [storyboard instantiateInitialViewController];
I have multiple storyboards within my app. I want to pass an object when a new storyboard is opened.
I'am doing this:
UIStoryboard* storyboard = [UIStoryboard storyboardWithName:#"SetupStoryboard" bundle:[NSBundle mainBundle]];
UINavigationController* initialHelpView = [storyboard instantiateInitialViewController];
SetupViewController *setup = (SetupViewController*) [initialHelpView topViewController];
setup.data = self.data;
initialHelpView.modalPresentationStyle = UIModalPresentationFormSheet;
[self presentViewController:initialHelpView animated:YES completion:nil];
But when the storyboard is presented the setup.data is nil in viewDidLoad, viewWillAppear etc of the SetupViewController...
Why is that?
I don't see anything wrong with this code. Problem may be elsewhere.