I'm trying to select which ViewController the AppDelegate should display based in a NSUserDefaults BOOL. But the HomeViewController does not display.
I'm using Storyboards and I have my own class of UINavigationController.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
[FBLoginView class];
[FBProfilePictureView class];
MeuNavigationController *nav = [[MeuNavigationController alloc]init];
if ([NSUD boolForChave:#"firstLogin"]==false) {
ViewController *viewC = [[ViewController alloc]init];
[nav pushViewController:viewC animated:NO];
}else{
HomeViewController *viewP = [[HomeViewController alloc]init];
[nav pushViewController:viewP animated:NO];
}
return YES;
}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
[FBLoginView class];
[FBProfilePictureView class];
UIViewController *controller = nil;
if ([NSUD boolForChave:#"firstLogin"]==false) {
controller = [[ViewController alloc]init];
}else{
controller = [[HomeViewController alloc]init];
}
self.window.rootViewController = [[MenuNavigationController alloc] initWithRootViewController:controller];
[self.window makeKeyAndVisible];
return YES;
}
You noted that you're doing this off of storyboard. You might want to consider making this change as well:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
[FBLoginView class];
[FBProfilePictureView class];
// Name of storyboard
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
UIViewController *controller = nil;
if ([NSUD boolForChave:#"firstLogin"]==false) {
controller = [[ViewController alloc]init];
// Set this in the storyboard's identity inspector
controller = [storyboard instantiateViewControllerWithIdentifier:#"ViewController"];
}else{
controller = [storyboard instantiateViewControllerWithIdentifier:#"HomeViewController"];
}
self.window.rootViewController = [[MenuNavigationController alloc] initWithRootViewController:controller];
[self.window makeKeyAndVisible];
return YES;
}
But you ask... Mr. jakenberg, how does one set their unique view controller identifier?
Cheers
Related
I am recieving push notification from backend but unable to go to specific controller from the click of push notification.
My Code is:
In appDelegate.m:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
NSDictionary* payLoad = [[launchOptions objectForKey:#"UIApplicationLaunchOptionsRemoteNotificationKey"] objectForKey:#"appsInfo"];
if ([[payLoad objectForKey:#"type"] isEqual: #"COURSE_DISTRIBUTE"]){
UIViewController *loginController = [[UIStoryboard storyboardWithName:#"iphone_Storyboard" bundle:nil] instantiateViewControllerWithIdentifier:#"EPAnalyticsViewController"]; //or the homeController
UINavigationController *navController = [[UINavigationController alloc]initWithRootViewController:loginController];
self.window.rootViewController = navController;
// [self.window makeKeyAndVisible];
} else if ([[payLoad objectForKey:#"type"] isEqual: #"ASSESSMENT_DISTRIBUTE"]){
UIViewController *loginController = [[UIStoryboard storyboardWithName:#"iphone_Storyboard" bundle:nil] instantiateViewControllerWithIdentifier:#"OUSTCardsViewController"]; //or the homeController
UINavigationController *navController = [[UINavigationController alloc]initWithRootViewController:loginController];
self.window.rootViewController = navController;
//[self.window makeKeyAndVisible];
}
In didReceiveRemoteNotification method I have Written:
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
NSLog(#"didReceiveRemoteNotification");
if ([[payLoad objectForKey:#"type"] isEqual: #"COURSE_DISTRIBUTE"]){
UIViewController *loginController = [[UIStoryboard storyboardWithName:#"iphone_Storyboard" bundle:nil] instantiateViewControllerWithIdentifier:#"EPAnalyticsViewController"]; //or the homeController
UINavigationController *navController = [[UINavigationController alloc]initWithRootViewController:loginController];
self.window.rootViewController = navController;
// [self.window makeKeyAndVisible];
} else if ([[payLoad objectForKey:#"type"] isEqual: #"ASSESSMENT_DISTRIBUTE"]){
UIViewController *loginController = [[UIStoryboard storyboardWithName:#"iphone_Storyboard" bundle:nil] instantiateViewControllerWithIdentifier:#"OUSTCardsViewController"]; //or the homeController
UINavigationController *navController = [[UINavigationController alloc]initWithRootViewController:loginController];
self.window.rootViewController = navController;
//[self.window makeKeyAndVisible];
}
}
On - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions you should set the root view controller.
And then on - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo you should use pushViewController or performSegue.
For e.g. -
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
UIViewController *loginController = [[UIStoryboard storyboardWithName:#"iphone_Storyboard" bundle:nil] instantiateViewControllerWithIdentifier:#"EPAnalyticsViewController"];
self.window.rootViewController = navController;
}
And now when you receive notification -
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
{
if ([[payLoad objectForKey:#"type"] isEqual: #"COURSE_DISTRIBUTE"]){
UIViewController *viewController = [[UIStoryboard storyboardWithName:#"iphone_Storyboard" bundle:nil] instantiateViewControllerWithIdentifier:#"EPAnalyticsViewController"];
[self.navigationController pushViewController:viewController]
} else if ([[payLoad objectForKey:#"type"] isEqual: #"ASSESSMENT_DISTRIBUTE"]){
UIViewController * viewController = [[UIStoryboard storyboardWithName:#"iphone_Storyboard" bundle:nil] instantiateViewControllerWithIdentifier:#"OUSTCardsViewController"];
[self.navigationController pushViewController:viewController]
}
}
When user open the app it show login UIViewController. When user log in it redirect to next mapkit UIViewController. But when user open app again I would like that he will skip login UIViewController. How can I do that? I tried programatically redirect in login method viewWillAppear but it works bad(It show controller for second).
A better way is to add this check in the AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
if(isLoggedin) {
Storyboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
UIViewController *mapViewController = [storyboard instantiateViewControllerWithIdentifier:#"mapViewController" ];
self.rootViewController = [[UINavigationCotroller alloc] initWithRootViewController:mapViewController];
}
return YES;
}
Instead of checking the login in the viewWillAppear: method of the first view controller, do it in the didFinishLaunchingWithOptions: method of your application delegate:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
if (loggedIn) {
UINavigationController *navigationController = (UINavigationController *)self.window.rootViewController;
[navigationController.topViewController performSegueWithIdentifier:#"1to2" sender:navigationController.topViewController];
return YES;
}
}
where 1to2 is the identifier of the segue from view controller 1 to 2.
You can do it like this:
AppDelegate.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// replace with your real auth-checking
if ([self wasAuthorized] == NO) {
[self showLoginController];
}
return YES;
}
- (UIViewController *)mainController {
UINavigationController *rootNavigationController = (UINavigationController *)[[self window] rootViewController];
return [[rootNavigationController viewControllers] firstObject];
}
- (void)showLoginController {
UIViewController *loginController = [self loginController];
dispatch_async(dispatch_get_main_queue(), ^{
[self.mainController presentViewController:loginController animated:YES completion:nil];
});
}
- (UIViewController *)loginController {
UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
return [mainStoryboard instantiateViewControllerWithIdentifier:#"LoginNavController"];
}
Hi i am trying to make UINavigationController but not in mainViewController(first viewControllerClass) , i need to put UINavigationController in second class. But If i will write these codes in appDelegate.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Override point for customization after application launch.
self.viewController = [[ViewController alloc] initWithNibName:#"ViewController" bundle:nil];
self.window.rootViewController = self.viewController;
// [window addSubview:[navigationController view]];
UINavigationController *navigation = [[UINavigationController alloc]initWithRootViewController:self.viewController];
self.window.rootViewController = navigation;
[self.window makeKeyAndVisible];
return YES;
}
Then UINavigationController appears in mainView. I am trying to put it in other class like that
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
// strWhichTaleOnScreen=[masivTaleNames objectAtIndex:indexPath.row];
NSString *selectDay;
selectDay=#"first string";
NSLog(#"selecDay=%#",selectDay);
classDetailOfMessagesViewController *nesneDetailOfMessagesViewController = [[classDetailOfMessagesViewController alloc] initWithNibName:#"classDetailOfMessagesViewController" bundle:nil];
nesneDetailOfMessagesViewController.selectDay = selectDay;
[navigation pushViewController: nesneDetailOfMessagesViewController animated:YES];
nesneDetailOfMessagesViewController = nil;
}
But it doesn't work, I guess i have to create rootViewController in this second view but i dont know how.
I ll be happy if someone can show me way to solve it out.
The first mistake i saw was you are trying to set the window rootviewcontroller twice. The view hierarchy needs to be like window->navigation controller->view controller. so I made some changes with your code.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Override point for customization after application launch.
self.viewController = [[ViewController alloc] initWithNibName:#"ViewController" bundle:nil];
UINavigationController *navigation = [[UINavigationController alloc]initWithRootViewController:self.viewController];
self.window.rootViewController = navigation;
[self.window makeKeyAndVisible];
return YES;
}
In the second code sample I couldn't find the reference to the navigation. And also if you push (in your case initWithRootViewController) a view controller to navigationcontroller stack you can access the navigation controller by self.navigationController so your second part of the code should be like this;
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSString *selectDay;
selectDay=#"first string";
NSLog(#"selecDay=%#",selectDay);
classDetailOfMessagesViewController *nesneDetailOfMessagesViewController = [[classDetailOfMessagesViewController alloc] initWithNibName:#"classDetailOfMessagesViewController" bundle:nil];
nesneDetailOfMessagesViewController.selectDay = selectDay;
[self.navigationController pushViewController: nesneDetailOfMessagesViewController animated:YES];
}
I am trying to add a static UINavigation bar that will be present on a nearly all ViewControllers in my project. The UINavigation bar will have the same 3 buttons throughout (one opens a side menu, one opens a search, one opens a ViewController to allow settings to be changed.
I have followed several tutorials (none are for Xcode5/iOS7) and these haven't worked for me.
Relevant code of "AppDelegate.m":
#import "AppDelegate.h"
#import "MainViewController.h"
#implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
UINavigationController *navVC = [[UINavigationController alloc] init];
MainViewController *mainVC = [[MainViewController alloc] init];
[navVC setViewControllers:[NSArray arrayWithObject:mainVC]];
[self.window setRootViewController:navVC];
return YES;
}
Running this gives the following error:
'NSInvalidArgumentException', reason: '*** -[__NSArrayM insertObject:atIndex:]: object cannot be nil'
MainViewController.m init
#implementation MainViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
Thanks,
Edit:
To Clarify, I am using a storyboard called 'Main', many ViewControllers with the first one being loaded called 'MainVC' which has a custom class called 'MainViewController'. Thanks to #LML the working code for this is now:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:#"Main"
bundle: nil];
MainViewController* mainVC = [mainStoryboard instantiateInitialViewController];
UINavigationController *navVC =[[UINavigationController alloc] initWithRootViewController:mainVC];
[self.window setRootViewController:navVC];
[_window makeKeyAndVisible];
return YES;
}
use this because you are using storyboard
-
(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:...{
// set to storyboard on launch
UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:#"iPhoneStoryboard"
bundle: nil];
MainViewController* mainVC = [mainStoryboard instantiateInitialViewController];
UINavigationController *navVC =[[UINavigationController alloc] initWithRootViewController:mainVC];
[self.window setRootViewController:navVC];
[window makeKeyAndVisible];
return YES;
}
Use [[UINavigationController alloc] initWithRootViewController:mainVC].
Try this in your didFinishLaunchingWithOptions method-
MainViewController *mainVC = [MainViewController alloc]initWithNibName:#"MainViewController" bundle:nil];
UINavigationController *navVC =[[UINavigationController alloc] initWithRootViewController:mainVC]; // Change here
[navVC setViewControllers:[NSArray arrayWithObject:mainVC]];
[self.window setRootViewController:navVC];
return YES;
I have 2 ViewController. loginViewControl which sets to rootViewControoler :
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
loginViewControl = [[LoginTab alloc] init];
self.window.rootViewController = loginViewControl;
[self.window makeKeyAndVisible];
return YES;
}
And I create StatusViewController :
*.h
#interface StatusViewController : UIViewController<UITabBarControllerDelegate>
{
IBOutlet UITabBarController *tabBarController;
IBOutlet UIButton *UploadButton;
IBOutlet UIButton *ConvertorButton;
IBOutlet UIButton *CompletedButton;
}
#property (nonatomic, retain) IBOutlet UITabBarController *tabBarController;
#end
Now I want to push StatusViewController from loginViewControl(rootviewcontroller).I used below code but it not work.
- (IBAction)statusButtonClick:(id)sender;
{
StatusViewController *statusView = [[StatusViewController alloc]init];
[self.navigationController pushViewController:statusView animated:YES];
[statusView release];
}
Do you have any suggestions? Thanks in advance
You not setting UINavigationViewcontroller at the didFinishLaunchingWithOptions of Window's RootViewcontroller, We can't Push a UIViewController without UINavigationViewcontroller
So First Set LoginViewController as a RootViewController of UINavigationViewcontroller like Bellow:-
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
loginViewControl = [[YourLoinViewcontroller alloc] initWithNibName:#"YourLoinViewcontroller" bundle:nil];
UINavigationController *objNavigationController=[[UINavigationController alloc]initWithRootViewController:loginViewControl];
self.window.rootViewController = objNavigationController;
[self.window makeKeyAndVisible];
return YES;
}
EDIT
Connect your StatusViewcontroller's view with File owner like bellow:-
your push method like this:-
- (IBAction)statusButtonClick:(id)sender;
{
StatusViewController *statusView = [[StatusViewController alloc]initWithNibName:#"StatusViewController" bundle:nil];
[self.navigationController pushViewController:statusView animated:YES];
}
Unless your login view controller is a navigation controller, self.navigationController in statusButtonClick will return nil and so this won't work.
Maybe you can try:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
loginViewControl = [[LoginTab alloc] init];
self.window.rootViewController = [[UINavigationController alloc] initWithRootViewController:loginViewControl];
[self.window makeKeyAndVisible];
return YES;
}
This will enclose a loginViewController in a navigationController which will permit you to push another viewController in the navigationController's stack.
- (IBAction)statusButtonClick:(id)sender; {
// If used StoryBoard
UIStoryboard *story=[UIStoryboard storyboardWithName:#"MainStoryboard" bundle:nil];
StatusViewController *statusView = [story instantiateViewControllerWithIdentifier:#"StatusViewController"];
[self.navigationController pushViewController:statusView animated:YES];
// If used XIB
StatusViewController *statusView = [[StatusViewController alloc]initWithNibName:#"StatusViewController" bundle:nil];
[self.navigationController pushViewController:statusView animated:YES]; }