Does loadView get called even if we don't override it in view controller like the other ViewController lifecycle methods? Even if we don't override the ViewDidLoad method, we know this lifecycle method will get called internally by ios. Does the same thing happen for LoadView also? or does it gets called only when the view inside the VC is nil or when we explicitly override it?
-
1Always gets called. Note the naming of the methods. `viewDidLoad()` is called as such precisely because it follows `loadView()`. – kid_x Apr 09 '20 at 01:10
2 Answers
It always gets called. From the documentation,
The view controller calls this method when its view property is requested but is currently nil. This method loads or creates a view and assigns it to the view property.
If the view controller has an associated nib file, this method loads the view from the nib file. A view controller has an associated nib file if the nibName property returns a non-nil value, which occurs if the view controller was instantiated from a storyboard, if you explicitly assigned it a nib file using the init(nibName:bundle:) method, or if iOS finds a nib file in the app bundle with a name based on the view controller'€™s class name. If the view controller does not have an associated nib file, this method creates a plain UIView object instead.
...
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.
It gets called even if you don't override it. Generally, you would only override it when you don't want to create a view controller from its nib. In this method, you would assign self.view
some value (since view
is loaded lazily). If you're not assigning some special subclass to your view property, you can usually get by by adding all your logic to viewDidLoad()
.
Here's a sample implementation:
// Say you have some custom view you want use as your controller's view
class CustomView: UIView { ... }
...
// In your view controller, you can set that custom instance to your view property.
override func loadView() {
self.view = CustomView()
}
UITableViewController
, for example, sets a UITableView
as your view (presumably) in this method.
By default, the view is just a vanilla UIView. If that's all you need, there's no reason to call this method at all. viewDidLoad()
is still a perfectly good place to do any additional initialization.
A couple of things to remember:
- only assign to your view in
loadView()
. Don't invoke it (on the right-hand side; don't invoke its getter), because that can cause an infinite loop. Ifview
is nil,loadView
gets called to create it. - Don't call
super.loadView()
. This method is meant to assign a view to your view property. By calling super, you'd be doing this twice.
A little more info on the infinite loop trap you could fall into:
From UIViewController's view:
If you access this property and its value is currently nil, the view controller automatically calls the loadView() method and returns the resulting view.
view
is created and assigned in loadView()
when it is nil. If you do that within loadView
itself, you will prompt loadView
to be called within its own body.

- 1,415
- 1
- 11
- 31
-
can you please elaborate on how it'll get into an infinite loop on calling the loadView explicitly? "only assign to your view in loadView(). Don't invoke it (on the right-hand side; don't invoke its getter), because that can cause an infinite loop" – pravir Apr 09 '20 at 08:56
-
I edited my answer to include a little more info. Have a look at [UIViewController.view] (https://developer.apple.com/documentation/uikit/uiviewcontroller/1621460-view). If `view` is nil, `loadView()` gets invoked to create it. Calling it within the body of `loadView()` is no exception. Invoke `view` when it is nil within `loadView()`, and `loadView()` will get called. Within `loadView()`, use `self.view` only on the left-hand side (only assign to it; don't call it or invoke its methods). `loadView()` is called in `self.view`'s getter, basically. – kid_x Apr 09 '20 at 18:05
Yes, it will still get called. You'll observe the same behavior as if you were to add this to your view controller.
override func loadView() {
// Only call this to observe this is being called.
// If you want to write your own implementation, you shouldn't call super.loadView().
// Instead, create your own UIView instance and set self.view = yourView.
super.loadView()
}

- 7,232
- 2
- 30
- 28
-
3Note to @pravir - you can do this to observe the method being called, but if you were to actually implement the method / fill in its body, you shouldn't call super.loadView() within it. – kid_x Apr 09 '20 at 00:56
-
Great note. I'll add comments to my original answer so people don't gloss over that. – AdamPro13 Apr 09 '20 at 17:56