UI Part 1 (UIViewController LifeCycle)

https://developer.apple.com/library/archive/referencelibrary/GettingStarted/DevelopiOSAppsSwift/WorkWithViewControllers.html

UIViewController

An object of the UIViewController class (and its subclasses) comes with a set of methods that manage its view hierarchy. iOS automatically calls these methods at appropriate times when a view controller transitions between states. When you create a view controller subclass (like the ViewController class you’ve been working with), it inherits the methods defined in UIViewController and lets you add your own custom behavior for each method.

loadView

--> If there’s already a view set, return that view--> Call loadView--> The default implementation of loadView in UIViewController does something like this--> If there’s an associated storyboard / xib,
--> Load the view hierarchy from the storyboard / xib
--> Assign the root view to the view property
--> If there’s no associated storyboard / xib
--> Create a UIView instance with a default frame and autoResizingMask
--> Assign that view to the view property
--> For any layout guides created from a storyboard / xib, setup --> --> Auto Layout constraints between the layout guides and the view of the view controller
--> Call viewDidLoad

Let’s dive into code

We created a LoginViewController from storyboard and we only override loadView method nothing more. As shown in Figure 1 we saw a black screen

Figure 1

As shown in Figure 2 we removed loadView override method which fix the problem. We can also fix this by calling super.loadView in loadView method . 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 initWithNibName: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.

Figure 2

As shown in Figure 3 we created only CustomViewController which don’t have any UI in the storyboard here we manually created root view.

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.

Figure 3

loadViewIfNeeded

If in case the view of current viewController has not been set yet then this method will load the view but remember, this is only available in iOS >=9.0. So if you are supporting iOS <9.0 then don't expect it to come into the picture.

Loads the view controller’s view if it has not already been set.

ViewDidLoad

As shown in Figure 4 on ViewDidLoad we got a wrong frame. Doing calculation on this you can imagine what can happen. Actual fram of the button when everything placed is x = 129, y= 183.0 , width =46 , height = 39

Figure 4

Why it is giving 1024 width because I used ViewTraits for iPad and Iphone currently my interface builder view is in iPAd which has different constraint than iphone. So in ViewDidLoad and viewWillAppear it is showing the interface builder structure not actually the device where it is running which is iPhone 11

Figure 4.1

By changing the View to Iphone 11 in interface builder I am getting the frame correct because device that is running is the same where we developed our interface

Figure 4.2

As shown in Figure 5 we created a label in Viewdidload by using the btn frame which gives wrong value on ViewdidLoad. Since btn is layout properly on relevant methods by autolayout engine but our label don;t

Figure 5

The natural place to put geometry related code is an event related to resizing and the layout of the main view. such as viewWillLayoutSubviews ut we need to be careful since this method is called multiple times over the life of a viewController that’s why we create UILabel one time at viewDidLoad and update its layout only in this method super cool

Figure 6

The second solution is to configure it for future layout by giving autolayout constraint on viewDidLoad . At this point constraint are not layout they are instructed as how this view should be resized and positioned by the runtime when layout does happen

https://www.amazon.com/Programming-iOS-13-Controllers-Frameworks-ebook/dp/B082FS7STT

ViewWillAppear

viewWillLayoutSubviews

This is the first step in the lifecycle where the bounds are finalised. If you are not using constraints or Auto Layout you probably want to update the subviews here. Called to notify the view controller that its view is about to layout its subviews

viewDidLayoutSubviews:

This event notifies the view controller that the subviews have been setup. It is a good place to make any changes to the subviews after they have been set. it only take places after all the auto layout or auto resizing calculations on the views have been applied. Meaning the method viewDidLayoutSubviews is called every time the view size changes and the view layout has been recalculated. Called to notify the view controller that its view is laid off

As shown in Figure 7 , initially we are in portrait mode , when we rotate device to landscape mode these methods get called and when this happens you get layoutSubViews things because your bounds change but you also get this animation for free . So iOS automatically animates the moving of your subviews from portrait layoutSubview to landscape layoutSubview

Figure 7

As shown in Figure 5 we solved the layout problem by using viewWillLayoutSubviews .

viewDidAppear

The viewDidAppear event fires after the view is presented on the screen. Which makes it a good place to get data from a backend service or database.

viewWillDisappear

The viewWillDisappear event fires when the view of presented viewController is about to disappear, dismiss, cover or hide behind other viewController.

viewDidDisappear

This is the last step of the lifecycle that anyone can address as this event fires just after the view of presented viewController has been disappeared, dismissed, covered or hidden.

Useful Links

https://www.amazon.com/Programming-iOS-13-Controllers-Frameworks/dp/1492074616

https://www.amazon.com/Programming-iOS-13-Controllers-Frameworks-ebook/dp/B082FS7STT