Get Notified of popViewController - ios

I need to save my data by calling a method I already have when a viewController is popped using the back button created by the UINavigationController.
Is there a way to get a delegate callback or a notification I didn't see anything in the documentation?

In your viewWillDisappear method, you can check the property:
[self isMovingFromParentViewController]
to find out if the view is disappearing as a result of being popped off the stack or not.

You will be notified that the view will be disappearing, with the view controller method viewWillDisappear:, however, this will be called each time the view is moved offscreen, whether that means the controller is popped or a new controller is pushed, or whatever else may cause your view to disappear.
Perhaps a better design would be to save your data in your controllers dealloc method. Normally, a navigation controller is the owner of a view pushed into it's stack, so popping it usually causes it to deallocate. This isn't always the case though and depends on how you've written your app.

Related

Order of viewWillAppear calls

If I have multiple view controllers being presented and dismissed in any order, can I be sure that iOS calls viewWillAppear methods in the right order (i.e. order of appearance)?
I cannot find any specific information about this in the documentation.
I think this is all you need to know about viewWillAppear from the docs:
This method is called before the view controller's view is about to be added to a view hierarchy and before any animations are configured for showing the view. You can override this method to perform custom tasks associated with displaying the view. For example, you might use this method to change the orientation or style of the status bar to coordinate with the orientation or style of the view being presented. If you override this method, you must call super at some point in your implementation.
Only thing that comes to mind that might not be absolutely clear is that this callback is called on the presenting view controller when presented view controller is going to be dismissed (so presenting view controller is going to appear again).
Therefore if A is a root, A.viewWillAppear will be called before it will appear on the screen. Then, if A presents B, just before B becomes visible, B.viewWillAppear will be called. And when B is being dismissed, A.viewWillAppear will get called again, since its view will appear again.
viewWillAppear() is called the first time the view is displayed and it is also called when the view is displayed again, so it can be called multiple times during the life of the view controller object.
It’s called when the view is about to appear as a result of the user tapping the back button, closing dialog, or when the view controller’s tab is selected in a tab bar controller, or a variety of other reasons. Make sure to call super.viewWillAppear() at some point in the implementation

Does viewDidload method call again on going back to a screen in navigation controller?

I am using navigation controller. I have pushed two viewcontroller to navigation stack. When I am coming back to viewcontroller1 from viewcontroller2 using back button of navigation bar then viewdidload method of viewcontroller1 is called again.But as much as I know viewdidload is called only once at loading time. So why is this happening? Please tell me.
Thanks!!
-(void)viewDidLoad called only when view controller is loaded
but if you want to call any method then you can write code in
-(void)viewWillAppear
this method called every time when your view is appear.
About viewDidLoad
viewDidLoad: is called every time your view controller's view is loaded, not just the first time. The controller's view can be loaded and unloaded multiple times during the lifespan of the controller and viewDidLoad will be called every time. It may be unloaded whenever it's not on screen, usually if memory is low.
Best practices
Remember not to do view controller initialisation in viewDidLoad. This is a common mistake. For stuff that should only happen once when the view controller is loaded, do it in one of the controller's init methods.
If you're popping/dismissing back to it, viewDidLoad is not generally called, but viewDidAppear will.
The exception to this is in iOS versions prior to 6.0, if you received a memory warning, your view could be unloaded, and it will be reloaded when you pop back.
As you are pushing the viewcontrollers, AFAIK they create a new instance of the view controller they are presenting. When you get back to viewController1 it's viewDidLoad will not be called but the viewController2 viewDidLoad will be called every time you move from viewController1 to viewController2. When you perform pop from viewController2 it is deallocated there itself

Popping view controller immediately after pushing it

I want the view controller to check something, and if it's true it would allow the user to use the view controller, and if it's false it would show an alert to the user and send the user back where he/she came from.
So I tried adding this to an if-statement at the end of viewDidLoad:
[self.navigationController popViewControllerAnimated:YES]
However, I got the error:
2014-08-09 20:12:59.731 ProjectName[1978:60b] nested pop animation can
result in corrupted navigation bar
2014-08-09 20:13:00.118 ProjectName[1978:60b] Finishing up a
navigation transition in an unexpected state. Navigation Bar subview
tree might get corrupted.
I learned from this StackOverflow question that calling pushViewController or popViewController before viewDidLoad finishes is unsafe. Are there any ways around this?
TLDR: I'm trying to push a view controller onto the stack, show an alert, then pop the view controller off of the stack.
EDIT: Added code.
This should be fairly easy provided you want to show the alert.
1 - Call [UIAlertView show] method from within viewDidAppear. It would be advisable to use viewDidAppear as it would be last in the view life cycle, when the view controller is fully pushed on the stack. So popping will be harmless.
2 - In clickedButtonAtIndex delegate method, call popViewControllerAnimated.

Why popping to root view controller results in calling viewDidLoad sometimes?

I have a navigation based application and in the child view I have a button, tapping on which results in calling the popToRootViewController method.
-(IBAction)popToRootViewController
{
[self.navigationController popToRootViewControllerAnimated:YES];
}
This should result in calling the viewWillAppear method of the rootViewController and it is happening in most of the cases. However, occasionally viewDidLoad of rootViewController is called. I am not able to find the reason behind it. Does any one has any idea why viewDidLoad is called sometimes?
On iOS 5 and Earlier, the System May Unload Views When Memory Is Low:
http://developer.apple.com/library/ios/#featuredarticles/ViewControllerPGforiPhoneOS/ViewLoadingandUnloading/ViewLoadingandUnloading.html
viewDidLoad is called once when view controller's view is loaded first time.
viewWillAppear will be called after viewDidLoad method when view controller's view is loaded first time.
Now when ever u push or pop controller in navigationController, the visible controller's viewWillApper method will be called surely.
viewDidLoad, as the name implies, is called just after a view controller has loaded its view. If a view controller is no longer the frontmost controller, it may release its view to save memory (and it used to call viewWillUnload and viewDidUnload which are now deprecated in iOS 6). If this happens, when it comes to front again (or whenever something calls thecontroller.view), it will recreate the view (if is not Nib-based, it will call loadView), and then call viewDidLoad.

ViewController won't update after load

I got two viewControllers using a navigation bar. The first viewController displays some data I change on the second viewController.
So if I load the second viewController, a back button appears in the NavBar and I can change my values (and they are stored, I used the debugger). My problem is, after hitting the backButton to come to my firstView Controller, it does not call it's viewDidLoad method. It's clear, that there are no updated values at all, when this function is not called.
At the first start, the viewDidLoad method is called and does what I want it to do. After going back and forth between the viewControllers the method is not called again.
Any solutions?
Thanks!
EDIT:
SOLVED
I did not want to delete my question, maybe someone needs this too:
This method is called every time the view appears, it is probably not defined by default:
-(void)viewDidAppear:(BOOL)animated
{
NSLog(#"View appeared.");
}
But the update code (like [[self view] setNeedsDisplay];) in viewWillAppear.
To make it clear: viewDidLoad is called when your view is loaded. This happens at the first time the view is going to be displayed. When you then navigate to the next view the first view can (depending on your code) still be loaded. Therefore when you navigate back to that view viewDidLoad won't be called because the view is still there.
But every time the view is going to be shown (for example when you navigate back to this view) the method viewWillAppear and viewDidAppear will be called.
Hope that helps.
ViewDidLoad method will get called when there is view controller allocation-initialization happens. In the case of moving back in navigation controller, it is not creating any new view controllers, it is reusing previous references from navigation stack.
Hence viewDidLoad will not get called. As your view controller is already in memory stack. So it will just make the view to reappear on windows and it will call viewWillAppear respectively.

Resources