View Controller lifecycle - iphone

Hi I have a resetView method that resets my view too a default state and that method gets called on loadView and when the device is shaken , the two view controllers are in a tab bar controller so when I change tabs the viewWillAppear method is call and resets the view but when close the application and it go's into the background the next time it is relaunched the view wont reset I have add the reset view method call in to
-(void)viewWillAppear:(BOOL)animated;
-(void)viewDidAppear:(BOOL)animated ;
- (void)viewDidLoad;
-(void)awakeFromNib;
but none of them are being called when the application is woken from the background

Look at the application delegate methods. You should call any methods from when the app is started from there. If your view was the last view when you left the app, none of the methods you listed should be called. Read the documentation about when they are called.

Related

viewDidAppear not firing ever again after app enters foreground

I have traced a problem in my iPhone app code to the viewDidAppear method not always firing. When you start the app the event fires as expected. However if I close the app using a phone capable of multitasking and reopen in. My viewDidAppear events no longer fire.
My views are loaded from Nibs and I use viewDidUnload to clean up (release and nil all outlets). My views are nested in side and tab bar then navigation controllers. I looks like the events aren't wired up properly when the nibs reload. Any idea on what I'm doing wrong/missing and how I can fix this?
Thanks in advance.
UPDATE I do not mean the event is not fired when the app first comes into the foreground. I mean the event never fires again. Even when changing between tabs or moving though the navigation views.
Example:
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
NSLog(#"viewDidAppear called");
}
This code is placed in two views, each on different tabs. Each time I swap between tabs "viewDidAppear called" is written to the log. When I close and reopen the app and swap between tabs this no longer happens. Other button events fire normally.
Btw, the viewDidUnload method is really badly named btw -- it's not an 'opposite' to viewDidLoad, it's only called if there was a low memory situation and the view for that controller was unloaded due to not being visible at that time.
(ORIGINAL, NOT SO RELEVANT ANSWER:)
Please see my answer to this similar question:
Why does viewWillAppear not get called when an app comes back from the background?
Basically, viewDidAppear gets called after your UIViewController's view was added to the application's UIWindow heirarchy. Backgrounding then restoring the app doesn't change your view in that respect, so viewDidAppear doesn't get called -- it's correct behaviour, and not a bug. Check out the API docs for UIViewController.
Found it.
While not new to programming I am new to iPhone development. On researching this problem I found it was not recommended to call the viewWillAppear and viewWillDisappear methods manually.
My viewWillDisappear methods resign any keyboards if shown, when my app enters the background it loads a splash screen ready for when the app re-enters the foreground (there is some logic I need to do to work out what the user is shown on restarting the app and I can do this under the splash screen).
As viewWillDisappear is not called when the app goes into the background to make sure no keyboards appeared over my splash screen I was calling viewWillDisapper in the applicationDidEnterBackground method. I guess this also un-registers my events.
By adding viewWillAppear to my applicationDidEnterForeground method my events started firing again. Lesson learned, I will refactor this so I don't call these events manually.
Thanks for the help.

Calling viewDidLoad while poping from a navigation class?

Interview question: For example, I have 3 classes A,B & C. I navigate from A -> B -> C, while pushing viewDidLoad function calls automatically and during popping viewWillAppear get called. But would it be possible to call my viewDidLoad function while popping?
No, Its not possible.Only viewDidAppear and viewWillAppear will be called by itself.You can call it manually.
All the best.
The viewDidLoad method is called when the view just loaded. Then viewWillAppear is called by the navigation controller when it's about to display the view.
If you want some code to be executed when the view is about to be displayed, be it when it's being pushed or when the top one is being popped, it makes more sense to use the appropriate method viewWillAppear for that, instead of trying to call the viewDidLoad method at a time when it isn't appropriate.
Can't you just move whatever code you have in viewDidLoad to viewWillAppear?
If the question is just "how can we call viewDidLoad while popping?", then it's simple:
- (void) viewWillDisappear:(BOOL)animated
{
[self viewDidLoad];
}
Just as a side note, if you have a view controller stack like A->B, it's possible that viewDidLoad will be called automatically on A when popping B if, while B was on top, the navigation controller unloaded A's view (if the app received a memory warning, for example)
You should not call viewDidLoad manually, it's not designed to be handled this way. Use viewWillAppear, as other users already mentioned.
As for the question whether it may happen that viewDidLoad will be called upon popping from a higher view controller: I imagine that may happen when the device got a low memory warning and unloaded the view controllers further down in the navigation hierarchy. Then the OS has to reload the view, I haven't however tested this and it's possible that this will never happen. The OS only unloads views when they don't have a superview, I didn't check whether upon pushing, views down the hierarchy actually get removed from the hierarchy.
ViewDidLoad should be for view creation.
ViewWillAppear - for Data Interaction if Server Request is Asynchronous. like calling API or any functionality.or any functionality we like to call when view going to appear.
ViewDidAppear - for Data Interaction if Server Request is synchronous.

loadView Vs init method

Please let me know at what times init and loadView method gets called.
To my knowledge init method gets called only once when view is initialized and loadView is called anytime view is loaded. So, even if you are pushing a new view in the view stack and then popping it then also the loadView of the poped up view should get called. But when I am running my code in debugging mode, both of these methods are getting called once, irrespective of how many times I am loading the same screen. Please let me know if I am missing something.
you are right at some points :)
The init method is being called when the ViewController object is instantiated. The loadView method gets called every time a ViewController should load its view into memory. This can happen before the view is displayed for the first time OR when it should be displayed for a second, third,... time but had been removed from memory before. (this might happen if your app runs out of memory.)
If you want to execute some code every time the view becomes visible, you should have a look at the methods viewWillAppear/viewWillDisappear/viewDidAppear/viewDidDisappear.
loadView is called when you access the view property of your view controller and it's nil.
If the view has been unloaded (viewDidUnload has been called for memory purpose) then loadView will be called again. If not it will not be called.
What you want is viewWillAppear: or viewDidAppear:.

How to know when a UIViewController view is shown after being in the background?

In iOS4.2/iPhone4
Click icon to launch app (some view
controllers view is displayed)
Click iPhone Home button (return to
home screen)
double click Home button
Select previously launched app from
the selection
Now I can see that my app delegate gets a message "applicationDidBecomeActive" when its selected after the last step, but how does my viewController (the one who's view is currently displayed) know?
viewDidLoad was already called, so that isn't called again. viewWillLoad is not called again.
Can't seem to figure it out. Reason I'm asking is I want to check to see if any Settings changes were made, but would like to do that in the view controller cause that's the thing that cares.
The answer is here: Handling applicationDidBecomeActive - "How can a view controller respond to the app becoming Active?"
Use NSNotificationCenter to get notified of UIApplicationDidBecomeActiveNotification events in your view controller.
in you're appDelegate applicationDidBecomeActive put this :
- (void)applicationDidBecomeActive:(UIApplication *)application
{
UINavigationController *navc = (UINavigationController *)[tabBarController selectedViewController];
UIViewController *topvc = [navc topViewController];
if ([topvc respondsToSelector:#selector(viewControllerDidBecomeActive)])
{
[topvc performSelector:#selector(viewControllerDidBecomeActive)];
}
}
This gets the viewController that is being seen on screen. You just have to implement viewControllerDidBecomeActive on every viewControllers ;)
In the appDelegate applicationDidBecomeActive set a boolean property marking that it just appeared from background.
Then in your viewcontroller, specifically in the viewDidAppear override, check for the appDelegate property, if its true then you know it has come from the background, otherwise it has just appeared as normal. BTW Afterwards, set the boolean property to false for neatness.
EDIT-
You would have to call viewDidAppear manually in the applicationDidBecomeActive unless you were re-creating your navigation stack. If you were able to get a pointer to the current visible view controller, then calling viewDidAppear should be a no fuss approach as all view controllers have this method. You wouldn't need any delegates or etc.

What is the program flow in case navigation based application developed for iphone in objective C?

I want to know the sequence in which default or predefined methods ( such as viewDidLoad applicationDidFinishLaunching etc) are called in program execution in a navigation based application.
See a life cycle for a view controller
init
loadView (if view wasn't specified with initWithNibName)
viewDidLoad
viewWillAppear
viewDidAppear
//here come some actions
viewWillDisappear
viewDidDisappear
viewDidUnload (in case of memory warnings)
Everything else depends on the sequence and methods (IB or through code) of instantiating of root view controllers.