why viewDidLoad gets called before viewWillAppear? [duplicate] - ios

This question already has answers here:
iOS 7 - Difference between viewDidLoad and viewDidAppear
(7 answers)
Closed 7 years ago.
I want to execute code before view appears but viewDidLoad is getting called before viewWillAppear. Why is it so??

ViewDidLoad is called when the view is loaded in to memory. i.e if you are using storyboard, the app has unarchived the view and loaded it into memory(not yet on screen).
When the app is ready to load the view on the screen it will call the viewWillAppear method.
In your case, if you want to execute code before the view appears on screen, you could add it in either viewDidLoad or viewWillAppear.

Because the view needs to load into memory before it can be displayed.
You need to read further about the view lifecycle. Check this link.
Only after the view and it's elements are loaded into memory, the view is painted on screen and viewWillAppear and viewDidAppear is called respectively.
If you need to execute code before view appears you need to use the viewWillAppear method.

I just wanted to provide some more information, maybe it will help you.
If you use constraints you may look on:
- viewDidLayoutSubviews()
Called to notify the view controller that its view has just laid out
its subviews.
So it will be called after your constraints applied.

Related

UIViewController lifecycle function loadview() frame question

I have been mainly working with storyboard until I recently moving to only creating controller with code.
I followed our coding standard to create some subview in the loadView() function, inside which, the first line is super.loadView().
From what I observed, after I called super.loadView(), the frame of self.view is already set correctly with the viewController itself, which is exactly the frame of the viewController.
My more experience colleagues are saying this was 100% not working in the old days that it should give u CGRectZero instead and probably I should not rely on it.
I want to hear more suggestion from other people.
Here is my sample project setup:
1. create a simple proj
2. add a button in the first VC
3. create second VC by code, override loadView() function in second VC, call super.loadView() there and print self.view.bounds next line
4. self.present or use navigation controller from VC1 in the button action to present or push to VC2
5. it always give me correct frame of the second VC.
Please let me know.
----------- Edit -------------
To clarify my question, I know the lifecycle functions like viewDidLayoutSubviews or layoutSubViews to return the correct view. I am NOT asking these.
My question is why loadView() IS returning me the CORRECT frame now.
Unfortunatelly I cannot give any insights as to what is happening under the hood - what I can do though, is tell you that according to the documentation you shouldn’t be calling super.loadView() :
You can override this method in order to create your views manually. If you choose to do so, assign the root view of your view hierarchy to the view property. The views you create should be unique instances and should not be shared with any other view controller object. Your custom implementation of this method should not call super.
(Emphasis mine)
1) I have been mainly working with storyboard until I recently moving to only creating controller with code.
I followed our coding standard to create some subview in the loadView() function, inside which, the first line is super.loadView().
Since you are using xibs, use viewDidLoad over loadView because of If you use Interface Builder to create your views and initialize the view controller, you must not override this method. as stated in loadView in Apple Docs.
2) My more experience colleagues are saying this was 100% not working in the old days that it should give u CGRectZero instead and probably I should not rely on it.
I want to hear more suggestion from other people.
The proper frame for the viewController.view will be when viewWillLayoutSubviews is called. As for its subviews, viewDidLayoutSubviews is what you will need
view frame inside loadView and viewDidLoad are Nib frame size. Your colleagues are correct that it will not return a proper size. This is noticeable upon running an iPad app with viewcontroller presented modally, or run your app on different screen size as contrast to what the device is in xib
ALSO, this question is directly related to yours:
Why am I having to manually set my view's frame in viewDidLoad?

What is viewDidLoad() for? [duplicate]

This question already has answers here:
Looking to understand the iOS UIViewController lifecycle
(11 answers)
iPhone SDK: what is the difference between loadView and viewDidLoad?
(8 answers)
Closed 5 years ago.
Can someone please help me understand what exactly viewDidLoad()does? I know it's called when the view controller is first loaded into memory. I addition, I am aware I can treat it as a main(). But I would like to know more about it. What does it reference too? UIView? It loads and treats all the buttons, labels, etc? Having a detailed and well explained overview would help!
In addition, I'm also confused about override. Does it add code to existent viewDidLoad()?
Thank you!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
P.S I am new here, feel free to leave any comments about my question formatting.
viewDidLoad is the method that is called once the MainView of a ViewController has been loaded. This is called after loadView is called.In the image you can see the MainView and other views within it. As soon as MainView has been loaded whatever will be included within the MainView you can get access to it (YES, all the buttons, labels, etc) in the ViewDidLoad method.
I'm also confused about override. Does it add code to existent viewDidLoad()?
As we know if subclass provides the specific implementation of the method that has been provided by one of its parent class, it is known as method overriding.
Here, the viewDidLoad in the superclass (UIViewController) is only an empty function. You need to Just override the function for your initial setup of the view once it has been loaded.
viewDidLoad is called when the ViewController has loaded its view hierarchy into memory. This is the point where you can perform your customized initialisation for your view controller.
For instance, if your view controller has a UILabel and you want to set a custom text to it, this is the point where you do that.

Why do I need to call addSubview if i'm immediately following it with addChildViewController [duplicate]

This question already has answers here:
What does addChildViewController actually do?
(4 answers)
Closed 7 years ago.
I'm pretty new to Objective-C and iOS.
I've noticed a familiar pattern in several apps, and I don't understand why it's necessary...
[someParentView addSubview:aChildViewController.view]
[self addChildViewController:aChildViewController]
From what I've read, you're not supposed to mess with a view controllers view directly, but rather just add the child view controller and the parent view controller will decide how and when to consult the childViewController's view.
In other words, when you've added a child viewcontroller to a parent viewcontroller, well obviously the parent viewcontroller has access to the child viewcontroller's view, hence calling addSubview seems not only redundant, but from what I've read, not recommended.
EDIT: Per a question below about more detail of what I'm doing...
I have a main storyboard view that covers the whole screen, and then I'm adding a view that takes only the left half of a vertical oriented screen. Users can tap on either the half view I added, or the remaining exposed half on the underlying full screen main storyboard view
Your main concern as I see is calling addSubview seems redundant?
I would say no it is not redundant, coz addChildViewController just Adds the given view controller as a child but it will not load/add the view.
This makes it essential to call addSubview
addSubview Add the child controller’s view as a subview.
For more info see:
Creating Custom Content View Controllers
Implementing a Custom Container View Controller
Refer the page, it will help you
http://www.objc.io/issue-1/containment-view-controller.html

viewWillAppear called again and again

Apple says in the viewWillAppear Documentation
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.
What does this sentence means
before any animations are configured for showing the view.
I am actually expecting the viewWillAppear to be called when the view is added in to the view hierarchy but when i come back from the background app to the foreground it also calls viewWillAppear when the view controller is already in the view hierarchy. Does it have to do some thing with the sentence
before any animations are configured for showing the view.
also the similar thing happens if i switch the tabs or some modal view controller is dismissed from my view.
The most classic and reliable method for the purpose you need is viewDidLoad.
viewWillAppear/viewWillDisappear and similar methods are designed to be called multiple times, viewDidLoad - only once, when the view first loads itself on the navigation stack, for example.

When are views and view controllers initialized/instantiated in iOS? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
I am new to iOS programming. I wonder when all the views and view controllers will be created.
At the time when the app launched all views and their controllers are created
or
when the view become active (displayed on the screen), it and its controller will be created(also, when it becomes inactive, it will be deallocated)?
Thanks!
The answer is neither really, but it depends on the structure of your app. The views are not created until you reference them, or the view is about to be put on screen. The controllers though can be instantiated at different times, that could be well before the view is created. For instance, when using a tab bar controller, all of the controllers are instantiated right after the tab bar controller itself, but only the view of the tab at index 0 is created and displayed. The other views are not loaded until you click on one of the other tabs. With segues, the controllers are created when the segue is called, and the views are loaded shortly thereafter (but after prepareForSegue is called in the calling class which is why you can't reference any of the destination controller's views in that method).
The view controllers and their views will be deallocated when there is no longer any strong pointer to them. Again, when that happens depends on how your app is set up. For instance, with a navigation controller, when you push to another controller, the initial one is not on screen any more, but the navigation controller has a strong reference to it, so it is not deallocated. However, when you pop a view controller (off the navigation controller's stack), it will be deallocated, unless you keep a pointer to it yourself.
I believe something happens in main() that initializes the app delegate when your app first starts. The app delegate initializes the window object which manages displaying content to your screen. The app delegate's application:didFinishLaunchingWithOptions is the entry point into our app's logic. Here is where you can initialize and set your root view controller although it's taken care of for you, especially if you're using storyboard.
After the root view controller is initialized it'll go through a series of steps setting up it's views.
viewDidLoad()
viewWillAppear()
viewDidAppear()
viewWillLayoutSubviews
are some events you can respond to as it's being set up. I assume somewhere between viewDidAppear and viewWillLayoutSubviews is when similar events are called for that view controller's subviews.
viewWillDisappear()
viewDidDisappear()
viewDidUnLoad()
are the other events of interest.
If you are using StoryBoards, the root view controller defined in it is the view that will be loaded at app launch after that, you control the flow of the application yourself with a navigation controller for example.
For controlling the life cycle of your views, your controllers and the app, the OS will send messages to your classes that represent events. These can be events of the app launching, the view appearing on the screen or a class being instantiated.
Here are a few examples:
When your app first launches, the OS will call application:didFinishLaunchingWithOptions: in your app delegate.
When a viewControlles's View is about to appear on the screen, the OS will call viewWillAppear() on the viewController.
When you create a view from the storyBoard, the method initWithCoder: get called on the view's class.
Here are some docs that explain it better: UIApplicationDelegate Protocol and View Controller Programming Guide: Resource Management.

Resources