When will viewWill/DidAppear/Disappear is called anyway and how exactly does it work? - objective-c

I understand that viewWillAppear will be called when duh.... when the the view is about to appear.
But how does IOS know that a controller's view is about to appear?
When exactly that and how it is implemented?
For example, does the childController.view check first that window is one of it's super ancestors? Does the view has a pointer to it's controller? How exactly that works? Does everytime a view is added it check whether it's window is it's super ancestor and whether it is the view outlet of a UIViewController?
For example, if I add childcontroller.view but not to a subview of any view that's being called. Will viewWillAppear called?
Does the childController need to be the a child of a parentController so that viewWillAppear of the childController will be called when the parentController's viewWillAppear is called automatically?

The view is loaded by your controller using the - (void)loadView method. This method is implemented to load a blank view or a view from a nib/storyboard. You only need to override it if you really need to create a view hierarchy from scratch.
All of the magic happens when the value of the view property is first requested and the controller detects the value is nil. All of the life cycle method calls are handled by the UIViewController. There is nothing you need to do other than implement the methods if you need them. Remember one thing: There is no guarantee the view has been loaded until the - (void)viewDidLoad method has been called.
Everything I've learned about controllers how they work has come from the View Controller Programming Guide.

Related

In what cases viewWillAppear be called?

A normal answer would be, when the view will appear.
Say I have a UIViewController. Let's call that vc.
Say I want vc to control a view.
so I do vc.view = controlledView;
I expect everytime controlledView is about to appear then [vc viewWillAppear] will be called.
It doesn't.
What's wrong?
Also viewDidLoad is also not called even after I do
[vc view]
Technically, vc.view is already loaded
if you are calling viewWillAppear in any other file , with other View instance then it will never call.
viewWillAppear method calls every time when go to that view and if you leave it and then again come or come-back , it will call again.
please must use 'Super' keyword as.
[super viewWillAppear] in WillAppear method.
According to docs
This method is called before the receiver’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.
viewWillAppear is always called when your view is about to appear, as name itself suggests.
If a view controller is presented by a view controller inside of a popover, this method is not invoked on the presenting view controller after the presented controller is dismissed.
Life Cycle of view controller goes like this:
When a viewcontroller is allocated and loaded, loadView is called then viewDidLoad is called. You can see the entire flow as in image.
Refer to this image
NOTE: This image is taken from this answer
The right answer is the following.
Did you add the child viewController as the child of the parent child view controller.
viewWillAppear will only be called for the parent view controller (the top screen view controller) unless the other viewController is declared as the child.
Then the parentViewController will pass on viewWillAppear events.

What exactly is the point of adding childViewController?

I got a parentViewController.
The parentViewController has 3 children.
AnnController,
BobController,
CharlieController
(not real name)
At any time only a view of one such controller may exist. Transition is done with:
[self transitionFromViewController:fromController toViewController:toViewController duration:duration options:options animations:animations completion:^(BOOL finished)
Everything works well.
But then what's the point of adding Ann, Bob, and Charlie as a child of Parent?
At first I thought it's so that viewWillAppear and viewWillDisappear got called automatically during transitionFromViewController
But it's called anyway whether the viewController is a child or not.
It could be so that viewWillAppear and viewWillDisappear got called when parents got called. But that's easy to do.
Of course, only the view that's actually in the view hiearchy of ParentController.view will have their viewWillAppear and viewWillDisappear be called right? Or is it?
So what's exactly does the fact that Ann, Bob, and Charlie is the child of Parent Controller do?
At the Parent's viewWillAppear, will it go through all of it's child and call their viewWillAppear if and only if the childController's view is part of the hierarchy? Or what?
Actually what does the fact that
Note: I am well aware of what view containtment mean. I asked what exactly does it do? For example, one of the answer said that it pass on rotation. Yes. But does it do so for all child or only child whose view is in the parentViewController.view hierarchy? Or what?
Short Anwwer:
adding childViewController allow you to redirect events in a view controller to other controllers that has been defined has its children.
Long Answer:
addChildViewController is part of iOS 5 and later. It is a feature called "view controller containment". The basic idea behind this is that you can embed your view controllers into other view controllers of your own. It is powerful because it allows you to write your own tabViewController or customNavigationController for e.g.
The main thing about View controller containment is that it tries to ensure that all contained view controllers will get the appropriate messages. An easy example will be when you rotate your device, if you didn't add the addChildViewController the rotation changes event won't be passed down to your view hierarchy.
The view cycle like the calls you are mentioning (viewWillAppear, viewWillDisappear) are managed by the view controller so it is a different story.
Take a look to the official doc to get a good understanding of the power of custom container controller.

Modal view controllers calling other's "viewDidLoad"

I have a bunch of pages I am chaining together and presenting as modal view controllers. THey all have viewDidLoad methods. It seems that when one is loaded though it calls the viewDidLoad methods of ones in the background too. How can I stop this? Thanks!
You can't. The viewDidLoad method will get called when the view is loaded. Asking a view controller for its view loads the view.
Consider moving code into your viewWillAppear:(BOOL)animated method. That way it will only get called before the view is actually shown to the user.

The relationship between UIViewController and UIView

I'm trying to understand how these two are connected. Every time you make a UIViewController does it also automatically come with its own UIView?
Also are these from Cocoa or Objective-C?
UIViewController is a Cocoa Touch class built for the purpose of managing UIViews. It expects to have a view hierarchy, but you don't "automatically" get a view (this is slightly inaccurate; see edit below). Usually you will obtain views by calling initWithNibName on your view controller.
There is some built-in magic in Interface Builder which knows that if File's Owner is a UIViewController (or subclass), there is a property called view. That's about it.
Once you have linked a view controller and a view, the view controller does a fair amount of work for you: it registers as a responder for view touch events, registers for device rotation notifications (and handles them automatically, if you wish), helps you take care of some of the details of animation, and handles low-memory conditions semi-automatically.
Edit: correction—if you don't call initWithNibName or set the view property manually, the view property getter will invoke loadView if view is nil. The default implementation of loadView will see if you've set nibBundle and nibName and attempt to load the view from there (which is why you don't have to call initWithNibName, most of the time), but if those properties aren't set, it will instantiate a UIView object with default values. So technically, yes, it does automatically come with its own UIView, but most of the time that's of little value.
UIViewController doesn't automatically come with a view. You have to make a view in the -loadView method. By default, this loads the view from the nib file you've specified. You can also override this method to make a custom view if you prefer not to use a nib.
Also, the view is not created right when the UIViewController is created. UIViewController uses a technique known as lazy-loading to defer the creation of a view until the view is actually accessed for the first time.

UIWindow and UIView addSubview Question

Does the addSubview method actually load the view into the application or not? The reason I am asking is because I have two two views in my application. The application delegate adds the two views as subviews and then brings one of the views up front. Now, I have a print statement in each of the viewDidLoad methods for each view. When I run the application, the application delegate loads the views as subViews and as each view is loaded, I actually see the console print out the statements that I placed in each of the viewDidLoad methods. Is this supposed to be doing this?
viewDidLoad is actually a method of UIViewController, not UIView. It gets called after the view gets loaded into memory (after your init method, but before the awakeFromNib). You'll notice that addSubview: takes a UIView as a parameter, so the view must have been loaded in order for the view to be added to another view. Otherwise you'd be trying to add an imaginary view.
In answer to your question, yes it is supposed to be doing this. viewDidLoad is called long before you addSubview. In fact, if you take out the addSubview: lines, you'll notice that it's still getting called (because you're creating the view's controller).
My understanding is that views are lazily loaded. If your viewcontroller has 10 view, they are not all loaded until you actually try to access them.