So the problem is--and this is new, this used to work in iOS 7-- when I comment out "FinishedLaunching", it rotates just fine but when I override this "FinishedLaunching" function to create the "window" myself, it fails to rotate. This is really strange. Any thoughts?
The reason I want to use FinishedLunching is because sometimes I want a different viewController to be the initial view controller.
Here is the code in my "FinishedLunching"
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:UIScreen.mainScreen.bounds];
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"MainStoryboard" bundle:nil];
UIViewController *viewController = // determine the initial view controller here and instantiate it with [storyboard instantiateViewControllerWithIdentifier:<storyboard id>];
self.window.rootViewController = viewController;
[self.window makeKeyAndVisible];
return YES;
}
The problem is that you are creating a new window with
self.window = [[UIWindow alloc] initWithFrame:UIScreen.mainScreen.bounds];
when the AppDelegate one that it automatically sets up for you that is perfectly fine to use, just use self.window without alloc-initing a new one
Related
I am using objective-c to develop a single view app which is targeted for 11.4 iOS, and the Xcode version is 9.4.1.
After creation, there are Main.storyboard and LaunchScreen.storyboard, I changed the background for Main.storyboard to yellow.
Then load rootViewController with blow codesnip:
self.window.rootViewController = [[UIStoryboard storyboardWithName:#"Main" bundle:nil] instantiateInitialViewController];
When I run the app, the app's background is black instead of yellow, what is wrong?
========================
add screenshot:
========================
add code for init rootviewcontroller:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen alloc] bounds]];
self.window.rootViewController = [[UIStoryboard storyboardWithName:#"Main" bundle:nil] instantiateViewControllerWithIdentifier:#"ViewController"];
self.window.backgroundColor = [UIColor whiteColor];
[self.window makeKeyAndVisible];
return YES;
}
=======================
I can confirm it is that code in didFinishLaunchingWithOptions failed, all work fine if I comment out those code in the method, don't know why.
Your do not need to fire any code to get your Main.storyboard initial view controller.
Delete the code and go to Project settings -> General tab here you will find Main Interface see if it is set to Main(your storyboard name)
Also check your in you storyboard that the entry point is set to your desired viewcontroller or not.
Run your project and see.
Use below code to get your view controller on start up,
self.window.rootViewController = [[UIStoryboard storyboardWithName:#"Main" bundle:nil] instantiateViewControllerWithIdentifier:#"yourViewController Storyboard ID."];
found the cause, the
initWithFrame:[[UIScreen alloc] bounds]
should be
initWithFrame:[[UIScreen mainScreen] bounds]
Use this code.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
self.window.rootViewController = [[UIStoryboard storyboardWithName:#"Main" bundle:nil] instantiateViewControllerWithIdentifier:#"ViewController"];
self.window.backgroundColor = [UIColor whiteColor];
[self.window makeKeyAndVisible];
return YES;
}
You have a “Main.storyboard” already added in the project.
Select its ViewController , go to property inspector . tick the “initial view controller” option.
Create View controller in the “Main.storyboard” say LoginVC , give it the Class and Storyboard ID
Create rootviewcontroller in app delegate.enter image description here
let mainStoryboardIpad : UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let initialViewControlleripad : UIViewController = mainStoryboardIpad.instantiateViewController(withIdentifier: "LoginVC") as UIViewController
self.window = UIWindow(frame: UIScreen.main.bounds)
self.window?.rootViewController = initialViewControlleripad
self.window?.makeKeyAndVisible()
I have tried using navigation view controller and setting up my screen as initial view controller using storyboard and it went well.
But when I did everything programmatically like below in my appDelegate.m file :
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
UIStoryboard *storyboard = [UIStoryboard storyboardWithName: #"Main" bundle:nil];
FirstViewController *firstVC = [storyboard instantiateViewControllerWithIdentifier:#"FirstViewController"];
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController: firstVC];
self.window =[[[UIApplication sharedApplication]delegate] window];
self.window.rootViewController = navController;
return YES;
}
My screen on the simulator is blank.
But when I checked the is initial view controller for the respective view controller in the storyboard and run. This time, it worked, and the expected screen is displayed.
My question is, why should I check the is initial view controller in the storyboard when I am doing everything programmatically ?.
Thank you.
If you're going to create the first view controller yourself in didFinishLaunchingWithOptions, you have to instantiate the UIWindow, too. But your assignment of self.window is just retrieving itself (lol) and does nothing. You'd generally do something like:
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
When you use the "initial view controller" option, it takes care of all of this for you, which is why that works when you check that option.
And don't forget to makeKeyAndVisible:
[self.window makeKeyAndVisible];
Thus:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
UIViewController *firstVC = [storyboard instantiateViewControllerWithIdentifier:#"FirstViewController"];
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController: firstVC];
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
self.window.rootViewController = navController;
[self.window makeKeyAndVisible];
return YES;
}
I'm using parse and I'm trying to get the login screen to show if the user isn't the "current" user. I'm having issues with my NavigationController (from my storyboard) and using it as the rootViewController even though it's already set as initial View Controller in my storyboard. Using this line of code I select the NavigationController (from my storyboard) and initialize it in my app delegate.
UINavigationController *navVC = (UINavigationController *)self.window.rootViewController;
I then decide whether or not to display the loginVC then finally I set the NavigationController as the rootViewController here:
self.window.rootViewController = navVC; [self.window makeKeyAndVisible];
Except someone I don't. I get this error when I try to build my app. "Application windows are expected to have a root view controller at the end of application launch" Anyone have any ideas what's going wrong?
Here's the code all together.
AppDelegate.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
self.window.backgroundColor = [UIColor whiteColor];
UINavigationController *navVC = (UINavigationController *)self.window.rootViewController;
// Initialize Parse.
[User registerSubclass];
[Question registerSubclass];
[Parse setApplicationId:#"HI"
clientKey:#"HI"];
// Determine whether or not to show the login screen
if (![PFUser currentUser]) {
LogInViewController *loginVC = [[LogInViewController alloc] init];
[navVC setViewControllers:#[loginVC] animated:YES];
} else {
QuestionsTableViewController *questionsVC = [[QuestionsTableViewController alloc] init];
[navVC setViewControllers:#[questionsVC] animated:YES];
}
self.window.rootViewController = navVC; [self.window makeKeyAndVisible];
return YES;
}
If you're starting with a storyboard you need to have it set as your Main Interface in the Deployment Info in your app's General settings. You should also remove the line:
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
..as it's initialising a new window in the place of the one created from the previous step.
I used these two lines of code to fix the issue. I got answer from here:
Programmatically set the initial view controller using Storyboards
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
UINavigationController *navVC = [storyboard instantiateViewControllerWithIdentifier:#"QuestionsView"];
I removed this line:
UINavigationController *navVC = (UINavigationController *)self.window.rootViewController;
There don't get the error anymore.
I'm developing an iOS 7+ app, and I've been told to set a different initial view for the app depending on a parameter I won't know until runtime. One of the possible initial UIViewController is an UITabBarViewController, and the other one is an UINavigationController.
Is it possible to manage this using a storyboard? Or is it the only way to use separated nib files?
Thanks
No need to use separate nib files, I do the same by following code in AppDelegate
- (BOOL)application:(UIApplication *)application willFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
UIStoryboard *storyboard = self.window.rootViewController.storyboard;
if(condition1) {
UITabBarController *rootViewController= [storyboard instantiateViewControllerWithIdentifier:#"TabbarController"];
[self setRootViewController:rootViewController];
} else if(condition2) {
UIViewController *rootViewController= [storyboard instantiateViewControllerWithIdentifier:#"ViewController"];
[self setRootViewController:rootViewController];
} else {
UIViewController *rootViewController= [storyboard instantiateViewControllerWithIdentifier:#"ViewController1"];
[self setRootViewController:rootViewController];
}
}
-(void)setRootViewController:(UIViewController *)rootViewController {
self.window.rootViewController = rootViewController;
[self.window makeKeyAndVisible];
}
You can specify the ID for your UITabBarViewController and UINavigationController in the storyboard.Then manually set the rootViewController of your app as the code below.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
UIStoryboard *board = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
self.window.rootViewController = [board instantiateViewControllerWithIdentifier:#"TabBarController"];
[self.window makeKeyAndVisible];
}
I'm not sure if I understood you right, but try to use JLRoutes. Set your TabBarController as initial view controller in one storyboard and navigation controller will be initial in other storyboard. Then navigate between them using JLRoutes
I followed some tutorial to create an open doors animation during the app launch but it's calling an
xib file and I want to call storyboard and I don' have enough experience with this.
Here's my code
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
// Override point for customization after application launch.
self.viewController = [[[OpenDoorsViewController alloc] initWithNibName:#"OpenDoorsViewController" bundle:nil] autorelease];
self.window.rootViewController = self.viewController;
[self.window makeKeyAndVisible];
return YES;
}
If you simply want to load the initial view controller of the storyboard when the app launches, just return YES in application:didFinishLaunchingWithOptions:.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
return YES;
}
If you want to load a specific controller from the storyboard, you need to first get the storybard instance by
UIStoryboard * storyboard = [UIStoryboard storyboardWithName:#"StoryboardName" bundle:nil];
then use it to instantiate the controller you need
UIViewController * controller = [storyboard instantiateViewControllerWithIdentifier:#"controllerIdentifier"];
where controllerIdentifier has been assigned as storyboard identifier to the controller in Interface Builder.
Here's an example loading a specific view controller, presenting it at launch.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
UIStoryboard * storyboard = [UIStoryboard storyboardWithName:#"StoryboardName" bundle:nil];
UIViewController * controller = [storyboard instantiateViewControllerWithIdentifier:#"controllerIdentifier"];
self.window.rootViewController = controller;
return YES;
}
If you start a new iOS project and select 'Use storyboards', the Storyboard will be automatically preloaded for you.
Storyboard is a place with all the controllers (scenes) of your app, and to reference one, you'll need to use
UIViewController *controller = [[UIStoryboard storyboardWithName:#"storyboard" bundle:[NSBundle mainBundle]] instantiateViewControllerWithIdentifier:#"an identifier"];