What gets called after UIApplicationDidBecomeActiveNotification gets triggered? - iphone

In my app I'm trying to make my navigation bar not shrink from 44px to 32px when the phone is rotated to horizontal orientation. I've been able to accomplish this by setting the navigationBars frame when the view is rotated and also in viewDidAppear. However, when I push the home button to exit the app and then I reenter the app, the navigation bar still shrinks. So I implemented a notification to detect UIApplicationDidBecomeActiveNotification, and in that method I reset the navigationBar frame height to 44px. However, it doesn't work because something is getting called which is resetting my views frame. Does anyone know what gets called after a UIApplicationDidBecomeActiveNotification gets triggered that resets the viewcontrollers frame?

In Your application any class can be an "observer" for different notifications. When you create view controller, you can register it as an observer for the UIApplicationDidBecomeActiveNotification and specify which method that you want call when that notification gets sent your your application.
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(myMethod:) name: UIApplicationDidBecomeActiveNotification object:nil];
remove observer in ViewWillDisappear/viewDidDisAppear/Dealloc as per your need:
[[NSNotificationCenter defaultCenter] removeObserver:self];

I'm having the same problem, if you attach an observer via Key Value Observers you can see that something is called after the UIApplicationDidBecomeActiveNotification.

Related

iPhone applicationWillResignActive - how to notify current UIView

I want to pause a timer on my game screen when the iPhone is locked etc. My question is what is the best method to notify the current UIView, which the AppDelegate has no direct access to?
1) Your timer should probably not be managed by the view but by the view's controller. The timer itself is not an inherent part of your UI, only the timer's display is. (What happens if you want to have the timer continue after a view is removed, for example?)
2) Any object (view or controller included) can independently listen for the appropriate notification. For example, in your view controller (or view code, if you choose to go that route):
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(pauseTheTimer:)
name:UIApplicationWillResignActiveNotification
object:nil];
Then implement a pauseTheTimer: method that will handle the notification. (Since there is only one UIApplication object, you can use nil for the object, as shown.)
This approach nicely decouples your app delegate from the views and view controllers.
(Oh, don't forget to stop observing when your view is unloaded or deallocated. Failure to do so can and will lead to crashes.)

Remove Modal View Controller when Application becomes active

In my app I have a button, when the user clicks it, it brings up a modal view controller which gets the user's location (with a UIActivityIndicator and image on). When it has there location it will send them off to another application.
This works well on older devices (without multi-tasking) because the app simply re-launches back to it's previous state after I go back to it.
However on devices that have multi-tasking, when I resume the app, the view that tells the user it's getting their location is still there - which is not at all desired.
My first idea was to set a BOOL when it was about to fire them off to the other app, and then in the viewDidAppear, if the BOOL is true, dismiss the modal view.
That would work, if viewDidAppear got called when an app resumes active. As I have just learnt, it doesn't.
Is there a method that view controllers can respond to when the app resumes active to that view? Or, will I have to set up delegation etc with the app delegate? If so, can you explain how I would do that?
You can send a notification when the app becomes active and listen to it into your modalviewcontroller. I think this is the easiest way.
// Into the app delegate
- (void)applicationDidBecomeActive:(UIApplication *)application
{
[[NSNotificationCenter defaultCenter] postNotificationName:#"ApplicationDidBecomeActive" object:nil];
}
// Into your modal view controller register it for the given notification
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(applicationDidBecomeActive:) name:#"ApplicationDidBecomeActive" object:nil];
- (void)applicationDidBecomeActive:(NSNotification *)notification
{
//...
}
Otherwise you can disable the background mode of your application by setting the "UIApplicationExitsOnSuspend" key to YES in the info.plist file.

NSNotification not being received in a UIViewController whose view is a subview of a UIScrollview

I'm trying to subscribe myViewController to a custom NSNotification. The view heirarchy looks like this:
window
- rootViewController.view
- scrollView
- myViewController.view
The notification is being sent to the [NSNotificationCenter defaultCenter] from a button inside the rootViewController's view. The rootViewController listens for the notification and responds to it just fine.
I have the same exact "listening" code inside myViewController, but it's not receiving the notification for some reason. If it's part of the app it should receive the notification, correct? I have a debug message inside myViewController's initWithNibName method, so I know that it's subscribing to the notification. I even tried having myViewController listen for ALL notifications by setting the notification name to nil. For example:
NSLog(#"main view controller initialized");
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(statusBarVisibilityChanged:) name:nil object:nil];
But no luck there either. Has anyone seen anything like this happen before with NSNotifications?
Any ideas?
Thanks!
I guess the view controller is deallocated. It's a common mistake not to retain a view controller when creating it programmatically.
If you are sure that the observation is set up correctly, my only explanation for not receiving any notifications is, that the controller is deallocated before any notifications are being sent.
The NSNotification mechanism is not dependent on neither view hierarchy nor thread. If you have a (living) object that has been set up as an observer it will definitely receive notifications.

App Delegate - Unload View Controller

I'm trying to unload a view controller from view when the iPhone goes to sleep. My app has a stopwatch that has to keep counting when the phone goes to sleep or call comes in or the user closes the app without logging out.
I have all this functionality in place, I'm capturing all start times and stop times and upon re-entering the stopwatch view controller, I calculate the difference. It all works beautifully. When I was doing some additional testing I realised I hadn't catered for the iPhone going into sleep mode.
So all I need to do to make sure my stopwatch is correct bring the user back to the app home screen. I know the following method is called when the app goes to sleep:
-(void)applicationWillResignActive:(UIApplication *)application
How do I unload the stopwatch view controller from my app delegate ?
---- UPDATE ----
kpower, thanks for your feedback. I've implemented the following code:
In my App Delegate:
- (void)applicationWillResignActive:(UIApplication *)application
{
[[NSNotificationCenter defaultCenter] postNotificationName:#"AppIsAsleep" object:nil];
}
In my view controller, I have the following:
-(void)viewDidLoad
{
// Add Observer.
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(viewDidUnload:) name:#"AppIsAsleep" object:nil];
}
- (void)viewDidUnload {
//Remove the Observer.
[[NSNotificationCenter defaultCenter] removeObserver:self name:#"AppIsAsleep" object:nil];
}
When the phone goes to sleep, it actually closes the app, am I doing something wrong ?
Regards,
Stephen
You can use the Notifications mechanism. It allows you to unload view controller from different place (not the AppDelegate) this case.
For example, in your view controller's viewDidLoad method you add an observer (don't forget to remove it in viewDidUnload) and in applicationWillResignActive: method of AppDelegate you just simply post notification. That's all.
↓ Update here ↓
When you get a notification - you should manage view controller's removing by yourself. And calling viewDidUnload here is not the solution, cause this method is called after view controller was already unloaded and doesn't cause removing.
How to remove? Depends on how the view controller was added (for example, popViewControllerAnimated for UINavigationController). The main idea here is to make object's retain count equal to 0 (as you know this case an object will be destroyed) - so you should sent release message necessary amount of times.

Refresh view in iPhone navigation based application

I am using a navigation based application for iPhone. I want to reload a view when i come back to it after pressing the back button. ANy solution?
Regards
Add a method viewWillAppear: to your controller class. In that method you can then update the view with current data.
The viewWillAppear: method will execute whenever the view is about to be displayed (after navigating to a different view using UINavigationController)
There is more than one, but I usually use NSNotificationCenters. You attach "listeners" for some kind of event, like this:
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:#selector(onSomethingChanged:)
name: #"somethingChangedEvent"
object: nil];
So, if some other view changes a setting, it notifies all the listeners like this:
[[NSNotificationCenter defaultCenter] postNotificationName: #"somethingChangedEvent" object: Nil];
Pretty simple and intuitive.