🌪️

ViewControllerのライフサイクル

2024/04/25に公開

この記事について

  1. ViewControllerについて知りたい人.
  2. UIKit勉強している人.
  3. 昔のSwiftの技術に興味がある人.

どんな仕組みなのか?

ViewControllerはViewDidLoadや、viewDidLayoutSubViewsなど、ViewControllerのViewの表示生成に関するメソッドや、レイアウト完了後に呼ばれるメソッドを保持しているそうです。

インターネットの情報を検索したのですが、図がみんな違うのでこれがわかりやすそうと思ったのを参考に作ってみました。

図は、ViewControllerのインスタンスが生成されてから、たどる処理のライフサイクルになります。

loadView, viewDidLoad

loadViewは、ViewControllerのviewがロードされている時に呼ばれるメソッドです。nib, xibなどを使用しない場合にカスタムViewの初期化を行うことができます。Appleのドキュメントによれば、Interface Builder を利用している場合は、このメソッドを呼び出してはいけないそうです。

https://developer.apple.com/documentation/uikit/uiviewcontroller/1621454-loadview

ViewDidLoadは、ViewControllerのviewがロードされた後に呼ばれるメソッドです。サブビューのセットアップはここで行います。

override func viewDidLoad() {
        super.viewDidLoad()
        
        button = UIButton(frame: CGRect(x: 100, y: 100, width: 200, height: 50)) // ボタンの位置とサイズを設定
        button.setTitle("Click Me", for: .normal) // ボタンのタイトルを設定
        button.setTitleColor(.black, for: .normal) // ボタンのタイトルの色を設定
        button.backgroundColor = .lightGray // ボタンの背景色を設定
        button.addTarget(self, action: #selector(buttonTapped(_:)), for: .touchUpInside)
        view.addSubview(button)
    }

viewWillAppear、viewDidAppear

viewWillAppearはviewが表示される直前に、何回も呼ばれます。loadView、viewDidLoadは一回しか呼ばれませんが、viewWillAppearは、その画面を表示する度に呼ばれます。

override func viewWillAppear(_ animated: Bool) {
        
    }

viewDidAppearは完全に画面遷移が完了し、スクリーン上に表示された時に呼ばれます。

override func viewDidAppear {
        super.viewDidAppear()
    }

viewWillDisappear、viewDidDisappear  viewWillDisappearは、ViewControllerのviewが表示されなくなる直前、dismissメソッドなどにより呼ばれます。

override func viewWillDisappear(_ animated: Bool) {
        
    }

viewDidDisappearは、完全に遷移が行われ、スクリーン上からViewControllerが表示されなくなったときに呼ばれます。

override func viewDidDisappear(_ animated: Bool) {
        
    }

注意すべき点としては、viewDidDisappearメソッドが呼び出されたからといってviewControllerオブジェクトが破棄されるわけではないということです。例えば、UITabBarControllerやUINavigationControllerなどに保持され続けている場合はviewControllerは保持されます。 viewWillLayoutSubviews、viewDidLayoutSubviews  viewWillLayoutSubviewsは、View Controllerのビューのframeが変更された時や、画面が回転される直前に呼ばれます。この時にはすでに画面の向きは決定しているので、画面の向きに応じた処理もここに記述することができます。

override func viewWillLayoutSubviews() {
        
    }

viewDidLayoutSubviewsは、View Controllerのビューのframeが変更された時や、画面が回転された後に呼ばれます。この時にsafeAreaInsetの値が決定します。

override func viewDidLayoutSubviews() {
        
    }

まとめ

今回は、ViewControllerのライフサイクルについて解説しました。StoryBoardやってたときに、みたことあったのですが当時は全然理解してませんでした😇

もしUIKitでボタンを作ってタップするとログを出すにはこれだけコードを書くみたいです。SwiftUIよりコード長くて難しい💦

import UIKit

class ViewController: UIViewController {
    
    var button: UIButton!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        button = UIButton(frame: CGRect(x: 100, y: 100, width: 200, height: 50)) // ボタンの位置とサイズを設定
        button.setTitle("Click Me", for: .normal) // ボタンのタイトルを設定
        button.setTitleColor(.black, for: .normal) // ボタンのタイトルの色を設定
        button.backgroundColor = .lightGray // ボタンの背景色を設定
        button.addTarget(self, action: #selector(buttonTapped(_:)), for: .touchUpInside)
        view.addSubview(button)
    }
    
    
    @objc private func buttonTapped(_ sender: UIButton) {
        // Called when the button is tapped
        print("call")
    }
}

やっとボタン1個表示できる。

Discussion