How to launch view controller from alarm notification action in iOS? - iphone

In my app i am using alarm functionality. It working fine. When i click the right button it launches my app. But i want to launch View Controller which is not an rootViewController. I am tried in searching in Google and SO but i couldn't get any idea or example.
I am looking for any example to achieve this.?
Thanks for your help guys.
EDIT
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Add the view controller's view to the window and display.
[self.window addSubview:alarmViewController.view];
[self.window makeKeyAndVisible];
application.applicationIconBadgeNumber = 0;
// Handle launching from a notification
UILocalNotification *localNotif =
[launchOptions objectForKey:UIApplicationLaunchOptionsLocalNotificationKey];
if (localNotif) {
NSLog(#"Recieved Notification %#",localNotif);
window = [[UIApplication sharedApplication] keyWindow];
UIViewController *rootViewController = [window rootViewController];
[rootViewController presentModalViewController:receipeViewController animated:YES];
}
// Override point for customization after application launch.
return YES;
}
- (void)application:(UIApplication *)app didReceiveLocalNotification:(UILocalNotification *)notif {
// Handle the notificaton when the app is running
NSLog(#"Recieved Notification %#",notif);
//Called here as well
window = [[UIApplication sharedApplication] keyWindow];
UIViewController *rootViewController = [window rootViewController];
[rootViewController presentModalViewController:receipeViewController animated:YES];
}

Finally Here's how I did it.
In didFinishLaunchingWithOptions:
//save the root view controller
[[self window] makeKeyAndVisible];
UINavigationController *navigationController = (UINavigationController*) self.window.rootViewController;
rootController = [[navigationController viewControllers] objectAtIndex:0];
Somewhere else in the app delegate:
[rootController performSegueWithIdentifier:#"destinationSegue" sender:self];
Then, in the storyboard, create a segue from the view that gets assigned to "rootController" to the desired optional view, and give that new segue the id destinationSegue. It takes some debugging to make sure the rootController variable gets assigned to the correct view.

You do not need to create a segue.You only need to assign an id in the storyboard for the ViewController.
[[self window] makeKeyAndVisible];
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
LensOverviewViewController *editLensViewController = [storyboard instantiateViewControllerWithIdentifier:#"lensOverView"];
UINavigationController *yourViewController = [[UINavigationController alloc] initWithRootViewController:editLensViewController];
[self.window.rootViewController presentViewController:yourViewController animated:NO completion:nil];
Normally [[self window] makeKeyAndVisible]; does not reside in the didFinishLaunchingWithOptions function but it needs to be called explicity to make the rootviewcontroller visible.

UIWindow *window = [[UIApplication sharedApplication] keyWindow];
UIViewcontroller *rootViewController = [window rootViewController];
[rootViewController presentModalViewController:alarmViewController animated:YES];

When your application is launched, look for the UIApplicationLaunchOptionsLocalNotificationKey on the launchOptions dictionary on the following method:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
This will let you know if your application is being launched because of a local notification (the one you use for the alarm).
You can also do something similar on:
- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification
Once you determine that you actually received a notification, just find the root view controller from the window and present the view controller you want to present modally.

Related

How to I connect Button Action to Tabbar Viewcontrollers

I am new to iPhone development. I am developing a TabBarViewcontroller App (iPhone and iPad) and in that I've created one LoginViewController and a Button Action.
My expectation is after clicking that Button, the control will move from LoginViewController to TabBarViewController. In this TabBarViewcontroller I have 5 Tabbar (items) ViewControllers.
Is it possible?
If you can, please share your ideas.
First of all, take UINavigationController and UITabbarController in your MainWindow.xib and bind IBOutlet to respective fields.. ans set LoginViewController as rootViewController of your UINavigationController..
Then in didFinishLaunchingWithOptions method write this..
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
[self.window setRootViewController:navController];
[self.window makeKeyAndVisible];
return YES;
}
Now create other method in AppDelegate.m like this..
-(void)loadApplication
{
[navController pushViewController:tabbarController animated:NO];
}
On your Login button action.. call this method as follows..
-(IBAction)btnLoginTapped:(id)sender
{
AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication]delegate];
[appDelegate loadApplication];
}
So in button action try following codes
AppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
appDelegate.window.rootViewController = tabBarController;
use this method to add tabbar from any other view..
-(void)addTabBarControllerInwindow
{
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:1.0];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromLeft forView:self.window cache:YES];
[self.navigationController.view removeFromSuperview];
[self.window addSubview:tabBarController.view];
[UIView commitAnimations];
}
put this method in AppDelegate.m file and in any viewController e.g. in LoginView Controller
when you want to add tabbar then declare object of delegate and call this method like bellow..
AppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
[appDelegate addTabBarControllerInwindow];
I think you might be looking for multiple VC in a single project. So declare and initialise a VC for loginVC and otherVCs(for tabbar) in appDelegate and after login successful call the following function.
On launch make LoginVC as RootViewController
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{// declare LoginVC and make it rootViewController
self.window.rootViewController = self._loginVCObj;
[self.window makeKeyAndVisible];
}
#pragma mark- Continue to next screen after successful Login
-(void) continueToNextView
{ // Handle UI after Login like.
[_loginVCObj._indicator stopAnimating];
[_loginVCObj._loginButton setEnabled:YES];
//add the VC to the tabbar
self._tabBarController.viewControllers = [NSArray arrayWithObjects:self.navigationControllerList,_favItemListNavObj, _toDoHereVC, _settingNavObj, nil];
// make tabbar as rootViewController
self.window.rootViewController = self._tabBarController;
}

Select second tab from ModalViewController

In my app delegate I load a view controller on top of my tabbar. This controller had three buttons on it, one to navigate to each tab. When the second button is pressed, I want to dismiss the view controller and go to the second tab. But this doesn't seem to work the normal way.
My AppDelegate:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
//-- Insert a delay of 5 seconds before the splash screen disappears
[NSThread sleepForTimeInterval:3.0];
// Set the tab bar controller as the window's root view controller and display.
self.window.rootViewController = self.tabBarController;
// Set StartView to load first
StartViewController *startViewController = [[StartViewController alloc] initWithNibName:#"StartView" bundle: nil];
[window addSubview: [startViewController view]];
[window makeKeyAndVisible];
[self.tabBarController presentModalViewController:startViewController animated:NO];
[startViewController release];
return YES;
}
And here is my current IBAction, which doesn't seem to work:
- (IBAction) toSecondView:(id)sender
{
// Show status bar
[[UIApplication sharedApplication] setStatusBarHidden:NO withAnimation:UIStatusBarAnimationNone];
[(UITabBarController *)self.parentViewController setSelectedIndex:1];
[self dismissModalViewControllerAnimated:NO];
}
I tried these too, without success:
self.tabBarController.selectedIndex = 1;
and
[self.tabBarController setSelectedIndex:1];
Can anyone help me out and explain me what I'm missing?
This happend because a below of reason.
You have added ViewController Onto the Window As a subView, no need to add SubView because you are already presenting that ViewController as ModalViewController.
Please Try as below.
-(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{
//-- Insert a delay of 5 seconds before the splash screen disappears
[NSThread sleepForTimeInterval:3.0];
// Set the tab bar controller as the window's root view controller and display.
self.window.rootViewController = self.tabBarController;
// Set StartView to load first
StartViewController *startViewController = [[StartViewController alloc] initWithNibName:#"StartView" bundle: nil];
//[window addSubview: [startViewController view]]; no need to add subView here
[window makeKeyAndVisible];
[self.tabBarController presentModalViewController:startViewController animated:NO];
[startViewController release];
return YES;
}
-(IBAction) toSecondView:(id)sender
{
// Show status bar
[[UIApplication sharedApplication] setStatusBarHidden:NO withAnimation:UIStatusBarAnimationNone];
//create delegate's class object for accessing tabBarController
AppDelegate* delegate=(AppDelegate*)[[UIApplication sharedApplication]delegate];
//instead of [(UITabBarController *)self.parentViewController setSelectedIndex:1];
//delegate.tabBarController your tabBarControler at which you have added viewController
[delegate.tabBarController setSelectedIndex:1];
[self dismissModalViewControllerAnimated:NO];
}

Modal LoginView with iPhone

I have a viewcontroller containing a TabController. Before this loads, I want a user to login so I can check what they have access to. In my AppDelegate, bot the rootViewController (with the tabs) and the LoginViewController are declared, and they're also wired up in IB:
I have this in my AppDelegate:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// [window addSubview:[rootController view]];
[window addSubview:[loginViewController view]];
[self.window makeKeyAndVisible];
return YES;
}
My plan was to dismiss the login form after authenticating and show the rootController, but the rootController displays straight away. I was going to do:
-(IBAction)DidClickLoginButton:(id)sender {
NotesAppDelegate *delegate = [[UIApplication sharedApplication] delegate];
[delegate.window addSubview:[delegate.rootController view]];
[self dismissModalViewControllerAnimated:YES];
}
Is there an easier way to do this? I can't see why the LoginViewController isn't presented.
EDIT: Eventually got this working by adding it to the rootController in my AppDelegate's didFinishLaunchingWithOptions method
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// [window addSubview:[rootController view]];
[self.window makeKeyAndVisible];
LoginViewController *loginViewController =[[LoginViewController alloc] initWithNibName:#"LoginView" bundle:nil];
[self.rootController presentModalViewController:loginViewController animated:YES];
return YES;
}
I think it's actually much easier to do things 100% programmatically rather than with Interface Builder. Either way, in application:didFinishLaunchingWithOptions:, you want to do something like this:
[rootViewController presentModalViewController:loginViewController animated:NO];
Then, after the user logs in, do:
[rootViewController dismissModalViewControllerAnimated:YES];
Yes it would. As you are adding the root controller view on the window, and this would make it appear above all (even above the login view) and then your login view gets dismissed behind the root view, which you cannot see.
EDIT:
One of the approach would be to have login controller above root in the beginning itself (root view controller presenting login view) and then happily dismiss the login view.

Presenting a UIViewController after local notification

In application:didFinishLaunchingWithOptions: I initialize a UINavigationController. Later, I add the UINavigationController to the window:
[self.window addSubview:navigationController.view]
This all works fine. Now I added local notifications to my app and when the user responds to one, I would like to present a UIViewController. So I thought I could override application:didReceiveLocalNotification: and in there, use my navigationController:
[navigationController pushViewController:someVC animated:YES];
However, this does not work. I did some debugging and noticed that while navigationController is not nil, navigationController.view has no superview, so I assume it is not being displayed.
So, my question is: where should I push my UIViewController so that it gets displayed?
In your AppDelegate.h add this:
//Under where you have <UIKit/UIKit.h>
extern NSString *localReceived;
In your AppDelegate.m add this:
//All the way on top where you import your viewControllers
NSString *localReceived = #"localReceived";
In your AppDelegate.m in the - (void)application:(UIApplication *)app didReceiveLocalNotification:(UILocalNotification *)localNotification;
method add this:
[[NSNotificationCenter defaultCenter] postNotificationName:localReceived object:self];
Make sure that your viewController is a navigationController
If it's not, do the following -- Add this piece of code to your - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions:
UINavigationController *nvcontrol = [[UINavigationController alloc] initWithRootViewController:viewController];
[window addSubview:nvcontrol.view];
[window makeKeyAndVisible];
Now -- in your viewController.m add this to your -viewDidLoad function
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(localAction) name:localReceived object:nil];
Make a -(void) localAction and in that method add your navigationController code to push to the next View Controller!
Hope that works for you. Works like a charm for me
So here it is, another solution with a different approach. It worked like a charm for me. check it out:
- (void)application:(UIApplication *)app didReceiveLocalNotification:(UILocalNotification *)localNotification{
UIStoryboard *sb = [UIStoryboard storyboardWithName:#"MainStoryboard" bundle:nil];
CustomViewController *cvc = (CustomViewController *)[storyboard instantiateViewControllerWithIdentifier:#"CustomVC"];
AnotherViewController *avc = (AnotherViewController *)[storyboard instantiateViewControllerWithIdentifier:#"AnotherVC"];
avc.someValue = #"Passing a value"; //Optional
UINavigationController *nav = (UINavigationController *) self.window.rootViewController;
nav.viewControllers = [NSArray arrayWithObjects:cvc,avc, nil];
[(UINavigationController *)self.window.rootViewController popToViewController:avc animated:TRUE];
[[UIApplication sharedApplication] cancelLocalNotification:localNotification];
//Cancel Just for not showing it anymore on the notifications list...
}

Most Elegant way to dismiss a presentModalViewController?

I have successfully shown a view upon launch that authenticates a user. Upon success, I want the presentModalViewController to no longer be visible and deallocate properly.
My code is as follows:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
// Add the tab bar controller's view to the window and display.
[self.window addSubview:tabBarController.view];
Overview *overview = [[Overview alloc] initWithNibName:#"Overview" bundle:nil];
[self.tabBarController presentModalViewController:overview animated:YES];
[overview release];
[self.window makeKeyAndVisible];
return YES;
}
In your modal viewcontroller you need a piece of code doing:
[self dismissModalViewControllerAnimated:YES];