I need to present a view when the user enters the app after having received a Local Notification.
I wrote the below code in the didReceiveLocalNotifications Method.
NotificationModelClass *remainderAlert = [[NotificationModelClass alloc]initWithNibName:#"NotificationModelClass" bundle:nil];
[remainderAlert showRemainderAlert1];
[self.viewController presentModalViewController:remainderAlert animated:YES];
It is working fine when the user enter the background through MainView Controller. But I want to present that view in any viewController.
Try something like this for presenting any where in the app:
#define AppDelegateObject ((AppDelegate *)[[UIApplication sharedApplication] delegate])
[AppDelegateObject.window.rootViewController presentModalViewController: remainderAlert animated:YES];
If your appdelegate is the receiver of the notification then do it like this:
[self.window.rootViewController presentModalViewController: remainderAlert animated:YES];
Related
My app receives remote push notifications and upon receiving them, i would like to take it to a specific view controller(pretty much all the time). I have seen code like this (on didReceiveRemoteNotification). I am using storyboard for my apps.
UIViewController *vc = self.window.rootViewController;
PushViewController *pvc = [vc.storyboard instantiateViewControllerWithIdentifier:#"someid"];
[vc presentViewController:pvc animated:YES completion:nil];
This seems straightforward enough. But will it have any impact on memory allocation, as it looks like every time a push notification arrives, we are instantiating a new view controller. Is this the best practice?
you can try something like:
PushViewController *vc = [self.storyboard instantiateViewControllerWithIdentifier:#"someid"];
[[UIApplication sharedApplication].keyWindow.rootViewController presentViewController:vc animated:YES completion:nil];
You dont need to allocate uiviewcontroller as rootview everytime unless you want to have a uiviewcontroller present your pushVC.
if you are doing this in app delegate, the get the storyboard reference by:
UIStoryboard *test=[UIStoryboard storyboardWithName:#"name" bundle:nil];
and then call
[test instantiateViewControllerWithIdentifier.....
The above code you have mentioned is fine. But the logic remains upto you on how to handle. If it is intended that you always want different VC's for your push notification, then it is fine.
Say if you get two push notification instantly where two VC's will be presented immediately. But you want just one screen for the Push then this will be in trouble.
If you want to have one pushViewController object then you can make it a global object and do a simple check like this
UIViewController *vc = self.window.rootViewController;
if(!pvc)
{
pvc = [vc.storyboard instantiateViewControllerWithIdentifier:#"someid"];
}
[vc updatePushViewControllerDependingOnPushNotificationObject:somePushObject];
[vc presentViewController:pvc animated:YES completion:nil];
I have an app that needs to open a specific view controller when notification is tapped. Here's what I have tried:
In this case, if i use this my app crashes when I tap the notification.
if([[[userInfo objectForKey:#"aps"]objectForKey:#"alert"] isEqualToString:#"You've got mail!"])
{
MTNotificationViewController *profile = [[MTNotificationViewController alloc] initWithNibName:#"MTNotificationViewController" bundle:nil];
[self.window.rootViewController presentViewController: profile animated:YES completion:nil];
}
If I use this the app doesn't redirect to the view controller that I want it to load. I also tried putting my code in an if statement to check if the app is UIApplicationStateInactive and UIApplicationStateBackground but I still get the same result.
if([[[userInfo objectForKey:#"aps"]objectForKey:#"alert"] isEqualToString:#"You've got mail!"])
{
MTNotificationViewController *profile = [[MTNotificationViewController alloc] initWithNibName:#"MTNotificationViewController" bundle:nil];
[navigation.visibleViewController.navigationController pushViewController:profile animated:YES];
}
Can somebody please help me.
Thanks!
I am trying to implement local notification and its working fine but my problem is when my application is in foreground and I got the push from the server it will alert me but when I tap on that alert and trying to redirect on my home view controller with the using this simple code in app-delegate file
- (void)didTapOnNotificationView:(CMNavBarNotificationView *)notificationView
{
UIStoryboard *storyboard = [[self.window rootViewController] storyboard];
HomeViewController *obj_home=[storyboard instantiateViewControllerWithIdentifier:#"Home"];
UINavigationController* navigationViewController_test=[[UINavigationController alloc]initWithRootViewController:[storyboard instantiateViewControllerWithIdentifier:#"Home"]];
[navigationViewController_test pushViewController:obj_home animated:YES];
}
With this code it will show only black screen,can any one tell me where i making the mistake? and yes for the local notification alert I am using third party tool (CMNavBarNotificationView) and using its delegate method (didTapOnNotificationView)
You need to link up the navigationcontroller with a viewcontroller currently in the navigation stack. Here in the below code I am using the rootviewcontroller to present/push the HomeviewController, you can replace it with any controller that you want.
- (void)didTapOnNotificationView:(CMNavBarNotificationView *)notificationView
{
UIStoryboard *storyboard = [[self.window rootViewController] storyboard];
HomeViewController *obj_home=[storyboard instantiateViewControllerWithIdentifier:#"Home"];
// either present the navigation controller as a modal
UINavigationController* navigationViewController_test=[[UINavigationController alloc]initWithRootViewController:obj_home];
[self.window.rootViewController presentViewController:navigationViewController_test animated:YES completion:^{}];
// OR push the home view. Here my rootViewController is a navigation controller, so I am pushing the home view directly from it. You can push it from any of the controller that is in the current navigation controller stack.
[(UINavigationController *)self.window.rootViewController pushViewController:obj_home animated:YES];
}
Hope this helps.
Why do I want to use presentModalViewController in AppDelegate?
- Processing didReceiveLocalNotification, so I can launch a seperate modalView on top of my app to process the notification
What does my view architecture look like?
- Using storyboards
- MainStoryBoard: ->TabBarController->NavigationController
What's happening?
- Nothing, that's the problem :-D
- When I press the action button from the UILocalNotification, the app opens, but just shows the last open view from the tabbarcontroller.
As you can see below my last effort was to present the modalViewController on top of that current view, like so:
[self.window.rootViewController.tabBarController.selectedViewController.navigationController presentModalViewController:navigationController animated:YES];
- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification {
UIApplicationState state = [application applicationState];
if (state == UIApplicationStateInactive) {
// Application was in the background when notification was delivered.
NSLog(#"Received notification while in the background");
}
else {
NSLog(#"Received notification while running.");
}
MedicationReminderViewController *controller = [[UIStoryboard storyboardWithName:#"ModalStoryBoard" bundle:nil] instantiateViewControllerWithIdentifier:#"MedicationReminderVC"];
UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:controller];
[self.window.rootViewController.tabBarController.selectedViewController.navigationController presentModalViewController:navigationController animated:YES];
}
Update
Seems that this is nil:
self.window.rootViewController.tabBarController.selectedViewController.navigationController
Solution
[self.window.rootViewController presentModalViewController:navigationController animated:YES];
Try this :
[self.window.rootViewController presentModalViewController:controller
animated:YES];
Have you tried the following?
[self.window.rootViewController.tabBarController.selectedViewController presentModalViewController:navigationController animated:YES];
That said, even if this works, I would really urge you to reconsider your design choices to avoid having to do this. Traversing the navigation stack in this way to access stuff can get very messy and I'd strongly advise against it.
I'm converting and iphone project to ipad. On iphone I have a mainViewController that opens a loginViewController using addSubView.
On the iPad I would like to display that loginViewController in a popover. so I did something like:
UIPopoverController *loginPop = [[UIPopoverController alloc] initWithContentViewController:loginViewController];
[loginPop presentPopoverFromRect:CGRectMake(150, 150, 90, 90) inView:self.view permittedArrowDirections:UIPopoverArrowDirectionAny animated:true];
This works fine. The problem is when the loginViewController finishes its "business". On the iPhone I just call a simple [self.view removeFromSuperview]; But on the ipad this causes the view to be removed from the PopoverController but the frame of the popup stays.
So my question is: is there any simple way from within the loginViewController to remove its PopoverController container (without using delegate or notifications)?
Yes, your loginViewController should keep a reference to the popover. Then you can use the dismissPopoverAnimated: method of your popover itself to remove it.
Actually, I want to implement that, but I remembered that we can access application delegate, which in turn will have access to main view of it, In there, you can store property of the popover, and you can call the dismissPopoverAnimated.
Like this :
MyAppDelegate *app = (MyAppDelegate *) [[UIApplication sharedApplication] delegate];
MyViewController * myView =[app viewController];
[myView.popover dismissPopoverAnimated:YES];