CS193p class Note 9: View Controller Lifecycle and Scroll View

##### Memo:

- `viewDidLoad`: Do not do geometry-related setup here. Bounds are not set yet. This method is only called once.

```swift
override func viewDidLoad() {
    super.viewDidLoad()   // always add this line
    // do the primary setup of my MVC here
    // good time to update my View using my Model because all the IBOutlets are set
}
```
- `viewWillAppear`: This method will be sent just before your MVC appears (or reappears) on screen. It can be called repeatedly.

```swift
override func viewWillAppear() {
    super.viewWillAppear()   // always add this line
    // catch my view up to date with what went on while I was off-screen.
}
```
- `viewDidAppear`: It is called after your MVC has finished appearing on screen. It is also a good place to put some time-consuming code (e.g. network fetching). 

```swift
override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)   // always add this line
    // maybe start a timer or an animation or start observing something(e.g. GPS position)
}
```
- `viewWillDisappear`: Your MVC is still on screen, but it's about to go off screen. (e.g. the user hit "back" in a `UINavigationController` or switched to another tab in `UITabBarController`)

```swift
override func viewWillDisappear(_ animated: Bool) {
    super.viewWillDisappear(animated)   // always add this line
    // often you undo what you did in viewDidAppear
    // for example, stop a timer and stop observing something
}
```
- `viewDidDisappear`: Your MVC went off screen. Somewhat rare to do something here, but occasionally you may want to "clean up" your MVC. For example, you could save some state or release some large, recreatable resource.

```swift
override func viewDidDisappear(_ animated: Bool) {
    super.viewDidDisappear(animated)   // always add this line
    // clean up MVC
}
```
- Geometry: You get notified when your top-level `view`'s bounds change (or otherwise needs a re-layout). Usually you don't need to do anything here because of `Autolayout`. These methods can be called quite often. So don't put anything not efficient here.
 - `override func viewWillLayoutSubviews()`
 - `override func viewDidLayoutSubviews()`

- `viewWillTransition`: It is called when your device rotates.

```swift
override func viewWillTransition(
    to size: CGSize,
    with coordinate: UIViewControllerTransitionCoordinator
)
```

- `didReceiveMemoryWarning`: It is rare, but occasionally your device will run low on memory. This usually a buildup of very large videos, images or maybe sounds.

```swift
override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // stop pointing to any large-memory things (i.e. let them go from the heap)
    // that I am not currently using and that I can recreate as needed
}
```
- `awakeFromNib`: This method is sent to all objects that come out of a storyboard.

```swift
override func awakeFromNib() {
    super.awakeFromNib()
    // can initialize stuff here, but it's VERY early
    // it happens way before outlets are set and before you're prepared as part of a segue.
}
```

- View Controller Lifecycle:

```text
Instantiated(usually from storyboard)
awkaeFromNib (only called when instantiated from a storyboard)
segue preparation happens
outlets get set
viewDidLoad
These pairs will be called each time your controller's view goes on/off screen
    viewWillAppear and viewDidAppear
    viewWillDisappear and ViewDidDisappear
These "geometry-changed" methods might be called at any time after viewDidLoad
    viewWillLayoutSubviews and viewDidLayoutSubviews
At any time, if memory gets low, you might get
    didReceiveMemoryWarning
```
- `scrollView`: 
  - contentSize: the space where the scrollView can scroll around
  - contentOffset: Where in the content is the scroll view currently positioned.
  - visibleRect: what area in a subview is currently visible.
  - zooming: All UIViews have a property (transform) which is an affine transform (translate, scale, rotate). Scroll view simply modifies this transform when you zoom. Zooming is also going to affect the scroll view's contentSize and contentOffset. Zooming will not work without minimum/maximum zoom scale being set and delegate method to specify view to zoom (`viewForZooming`).