This is my escenario:
I have a view controller where the user can go to another application (Settings) when push a button in this way:
-(void) goToSettings{
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:UIApplicationOpenSettingsURLString]];
}
So, this code open the app's screen settings and it shows in the upper left corner a legend like this:
Back to myApplication
I wish to detect when the view controller where user push the button is active again. I know you can detect when app is active again with this method in the delegate file
- (void)applicationWillEnterForeground:(UIApplication *)application
But I need detect in specific the view controller. I have tried with -(void)viewWillAppear:(BOOL)animated but It not works. Anyone have any idea about this?
Setup your view controller to listen for the UIApplicationDidBecomeActiveNotification notification.
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(becomeActive:) name:UIApplicationDidBecomeActiveNotification object:nil];
Then add the becomeActive: method:
- (void)becomeActive:(NSNotification *)notification {
// App is active again - do something useful
}
And be sure to remove the observer at the appropriate point.
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationDidBecomeActiveNotification object:nil];
Of course your app may become active again for lots of reasons, not just returning from the Settings app.
Related
I know you can listen for notifications for such app state, but... is it possible to know that way?
I need to know when the view is going to disappear because of another view is being shown, and not because the app is going to background state.
Thanks
viewWillAppear: and viewDidAppear: will not get called when app is going to background/returning to front as the state of the view in relation to the app isn't changing.
you can only observe the UIApplicationDidEnterBG / willEnterFG notifications
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(onAppWillEnterForeground:)
name:UIApplicationWillEnterForegroundNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(onAppDidEnterBackground:)
name:UIApplicationDidEnterBackgroundNotification object:nil];
NOTE: if you add observers in willAppear and remove them in didDisappear you can fake willDisappear/viewDidAppear yourself
You should register a UIApplicationWillEnterForegroundNotification in your ViewController's viewDidLoad method and whenever app comes back from background you can do whatever you want to do in the method registered for notification. ViewController's viewWillAppear or viewDidAppear won't be called when app comes back from background to foreground.
-(void)viewDidLoad{
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(doYourMethod)
name:UIApplicationWillEnterForegroundNotification
object:nil];
}
-(void)doYourMethod{
// do whatever you want to do when app comes back from background.
}
Don't forget to unregister the notification you are registered for.
-(void)dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
You mean viewWillDisappear ? If so, when app is going to background, viewWillDisappearwould not be invoked, so is viewDidDisappear, you can observe the notifications as #Daij-Djan said.
About viewWillDisapper, Apple says
This method is called in response to a view being removed from a view hierarchy. This method is called before the view is actually removed and before any animations are configured.
I am doing one application.In that i have some view controllers as like A->B,A->C,A->D and B->E,C->F,D->G and E->H,F->I and G->J.So i am in E view controller,whenever notification comes,i have to move to G view controller.And if i am in any view controller except G,i need to move to G view controller.So please tell me how to do it.
You need to first set some code in your AppDelegate.m to respond to pushes when the app is open:
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
{
//If opening app from notification
if ( application.applicationState == UIApplicationStateInactive || application.applicationState == UIApplicationStateBackground )
{
//restore push
[[NSNotificationCenter defaultCenter] postNotificationName:#"appRestorePush" object:nil];
}
//If app is already open
else {
[[NSNotificationCenter defaultCenter] postNotificationName:#"appOpenPush" object:nil];
}
}
Here we fire a NSNotification if the app is open from a push (i.e. you slide on it from the lock screen) and there is also a different notification for if the app is already open. You don't have to use two different types of NSNotification but it might be useful to you. I'm not really sure what your view controller setup is but assuming you are using a UINavigation controller for everything in the root controller you just set it up to listen in the ViewDidLoad i.e:
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(appOpenPush) name:#"appOpenPush" object:nil];
and in the method you call something like this:
-(void)appOpenPush {
NSLog(#"got a push while app was open");
//Get the view controller
UIViewController *lastViewController = [[self.navigationController viewControllers] lastObject];
if([lastViewController isKindOfClass:[MyViewController class]]) {
//do your segue here
}
else if//////do this for all your cases...
}
Here we are checking what type of class the view controller is and then choosing the appropriate segue.
Hope you have done a little work at least and understand what I wrote..
How to dismiss a view controller when the user is minimize/inactive the application.
Situation
- when user pressed on button. the app will be minimize, when user active back the application, user need to sign in again the application.
Use NSNotificationCenter to be alerted when the application will enter the background. Add the following in the view controller you want to handle this stuff in, such as the init or viewDidLoad methods:
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(methodToHandleItHere) name:UIApplicationWillEnterBackgroundNotification object:nil];
Then handle it accordingly:
- (void)methodToHandleItHere {
// handle it
}
I want to reload a webview in my view controller when my app comes to the foreground. I have created a view controller object in my application delegate's -applicationWillEnterForeground and -applicationDidBecomeActive methods. But I am not able to refresh my webview.
applicationWillEnterForeground may not be the best way to do it.
In the class that contains the webView add a notification method like below
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(didEnterForeground)
name:UIApplicationWillEnterForegroundNotification
object:nil];
-(void) didEnterForeGround
{
//[webView reload];
}
When your application comes to Foreground is app is active state , in particular view controller on viewdidload or viewdidAppear Method [WEBVIEW ReloadData]; thats it , you donot wan to do any thing in appdelegate class
Hello,
I am writing an app that should respond with an UI update and an internal status change when a local notifcation is used to open it. I am using storyboards and I have set up my main view controller to observe status changes:
- (void)viewDidLoad
{
[super viewDidLoad];
// ...
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(resumeByNotification:) name:#"Resume" object:nil];
}
In my app delegate I have this:
- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification
{
if (application.applicationState == UIApplicationStateInactive)
{
[[NSNotificationCenter defaultCenter] postNotificationName:#"Resume" object:self userInfo:notification.userInfo];
}
}
And this works just fine: if the app is running in the background, the view controller will intercept the notification and react accordingly. (If the app is running in the foreground, it's ignored because the UI is being taken care of directly.)
The problem arises when the app has been killed and the notification is received. I have written this in the didFinishLaunchingWithOptions method, making the phone vibrate as a quick debug technique :), and I do get the notification:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
UILocalNotification *localNotification = launchOptions[UIApplicationLaunchOptionsLocalNotificationKey];
if (localNotification)
{
[[NSNotificationCenter defaultCenter] postNotificationName:#"Resume" object:self userInfo:localNotification.userInfo];
AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);
}
return YES;
}
The phone DOES vibrate so the notification IS there, but it doesn't seem to trigger the observer. I suppose that this is because the view controller's didViewLoad method hasn't been called yet. I am not sure how to work this around. I suppose I could use UIStoryboard's instantiateViewControllerWithIdentifier: method to make sure the view controller is actually there, but wouldn't I be getting an "extra" instance of it, in addition to the one that will eventually be instantiated by the storyboard's own life cycle? Judging from what the on the class reference documentation says, it's not exactly meant to do this kind of thing.
Am I missing something very obvious here? In fact, is my approach the correct one for this kind of situation?
Thanks!
The view controller doesn't load its view until something asks it for its view. At launch time, that normally happens after application:didFinishLaunchingWithOptions: returns.
You might wonder why. The answer is that you might instantiate several view controllers at launch time, some of which are hidden. For example, if your window's root view controller is a UINavigationController, you might load the navigation controller with a stack of view controllers (the stack that the user had pushed the last time the app ran). Only the top view controller of this stack is visible, so there's no need to load the views of the other view controllers. The system waits until application:didFinishLaunchingWithOptions: returns before loading any views so that only the necessary views will be loaded.
So one way to work around your problem would simply be to ask the view controller for its view, thus forcing it to load. If your view controller is the window's root view controller, you can do it this way:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
UILocalNotification *localNotification = launchOptions[UIApplicationLaunchOptionsLocalNotificationKey];
if (localNotification) {
[[self.window rootViewController] view];
[[NSNotificationCenter defaultCenter] postNotificationName:#"Resume" object:self userInfo:localNotification.userInfo];
AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);
}
return YES;
}
A different workaround would be to start observing the notification in your view controller's initWithCoder: method:
- (id)initWithCoder:(NSCoder *)aDecoder {
if (self = [super initWithCoder:aDecoder]) {
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(resumeByNotification:) name:#"Resume" object:nil];
}
return self;
}
This is called when the view controller is instantiated from the MainStoryboard, which happens before the application:didFinishLaunchingWithOptions: message.