こんにちは、こばやしよしのり @yoshiii514 です。
UIViewControllerのライフサイクルについて解説します。
【目 次】
前提知識
Xcode、Swiftの基礎学習をしていることが前提になります。初学者の方は、次の記事を参考に基礎学習を済ませてください。
初心者向け iPhone(iOS)アプリ開発おすすめ本と勉強方法!
UIViewControllerのライフサイクル
次の図は、ViewControllerのビューで発生する表示状態と、発生する状態遷移です。Apple公式ドキュメントにあった図を加工しました。
iOSは、ViewControllerが状態間を遷移する適切なタイミングで、これらのメソッドを自動的に呼び出す。
- Willが「〜するつもり」の意味なので、Will系のメソッドはある行為が確定する前に呼び出される。
- Didが、doの過去形になり「〜した」を示すので、Did系のメソッドはある行為が確定した後に呼び出される。
- Appearが「登場する」の意味なので、Appearはこれから作っていく段階を示します。
- Disappearが「退場する」の意味なので、Disappearはこれから終了していく段階を示します。
iOSでは次のようにUIViewControllerのメソッドを呼び出します。
①viewDidLoad
override func viewDidLoad() {
super.viewDidLoad()
....
}
直訳すると「ビューがロードした」。
UIViewControllerのライフサイクルに入るための、はじめのメソッド。
ViewControllerのコンテンツビュー(ビュー階層の最上位、ユーザーが作ったビュー)が作成され、storyboardからロードされたときに呼びだす。
ViewControllerのoutlets(アウトレット接続)は、このメソッドが呼び出されるまでに有効な値を持つことが保証されているので、ViewControllerに必要な追加のセットアップを実行できる。
iOSはviewDidLoad()、コンテンツビューが最初に作成されたときに1回だけ呼びだす。ただし、コンテンツビューは、コントローラーが最初にインスタンス化されたときに必ずしも作成されるとは限らない。代わりに、システムまたはコードがViewControllerのプロパティに初めてアクセスしたときに、遅延して作成される。
②viewWillAppear
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
....
}
直訳すると「ビューが表示される」。
ViewControllerのコンテンツビューがアプリのビュー階層に追加される直前に呼び出される。
コンテンツビューが画面に表示される前に実行する必要のある操作を実行できる。
コンテンツビューの表示・非表示で呼び出されない。コンテンツビューがアプリのビュー階層に追加される行為で呼び出される。
③viewDidAppear
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
....
}
直訳すると「ビューが表示された」。
ViewControllerのコンテンツビューがアプリのビュー階層に追加された直後に呼び出される。
このメソッドを使用して、データのフェッチやアニメーションの表示など、ビューが画面に表示されるとすぐに必要となる操作を実行する。
コンテンツビューの表示・非表示で呼び出されない。コンテンツビューがアプリのビュー階層に追加される行為で呼び出される。
④viewWillDisappear
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
....
}
直訳すると「ビューが消えてしまう」。
ViewControllerのコンテンツビューがアプリのビュー階層から削除される直前に呼び出される。
変更のコミットなどの、後処理(クリーンアップタスク)を実行する。
コンテンツビューの表示・非表示で呼び出されない。コンテンツビューがアプリのビュー階層から削除される行為で呼び出される。
⑤viewDidDisappear
override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
....
}
直訳すると「ビューが消えた」。
ViewControllerのコンテンツビューがアプリのビュー階層から削除された直後に呼び出される。
追加の終了処理を実行します。
コンテンツビューの表示・非表示で呼び出されない。コンテンツビューがアプリのビュー階層から削除される行為で呼び出される。
2つのUIViewControllerをSegue(セグエ)でつないだときのライフサイクル
画面Aはタップして、画面Bに遷移します。
画面Bでは下にスワイプすると画面Aに戻ります。
Segueの種類はshowです。
各メソッドでprintにてデバックログに出力します。
検証1.画面Aが起動したとき
追加部分が赤字です。
画面A:viewWillAppear
画面A:viewDidAppear
検証2.画面Aから画面Bに遷移したとき
検証1からのすべてのログをだしてます。追加部分が赤字です。
画面A:viewWillAppear
画面A:viewDidAppear
—画面B:viewDidLoad
—画面B:viewWillAppear
—画面B:viewDidAppear
画面AのviewWillDisappearやviewDidDisappearが発生していないことがわかります。画面Aから画面Bに遷移するときは、画面Aの表示状態が保たれたまま遷移していることがわかります。
検証3.画面Bをスワイプして画面Aに遷移したとき
検証1からのすべてのログをだしてます。追加部分が赤字です。
画面A:viewWillAppear
画面A:viewDidAppear
—画面B:viewDidLoad
—画面B:viewWillAppear
—画面B:viewDidAppear
—画面B:viewWillDisappear
—画面B:viewDidDisappear
画面Bを完全に非表示(終了)して、画面Aに戻っていることがわかります。そのとき、画面Aの状態は表示したままで、なにも変化がないことがわかります。
検証4.再度、画面Aから画面Bに遷移したとき
検証1からのすべてのログをだしてます。追加部分が赤字です。
画面A:viewWillAppear
画面A:viewDidAppear
—画面B:viewDidLoad
—画面B:viewWillAppear
—画面B:viewDidAppear
—画面B:viewWillDisappear
—画面B:viewDidDisappear
—画面B:viewDidLoad
—画面B:viewWillAppear
—画面B:viewDidAppear
再度、画面Bを表示するときは、もう一度、最初から画面を作り直していることがわかります。
UITabBarControllerのライフサイクル
タブで画面を切り替えるUITabBarControllerがありますが、UITabBarControllerのライフサイクルは、UIViewControllerのライフサイクルとは違います。
UITabBarControllerのライフサイクルは次の記事で解説しています。
[Swift,iOS]UITabBarController Lifecycle(ライフサイクル)の解説
サンプルコードの保管場所
検証で使ったXcodeプロジェクトは次の場所にあります。
https://github.com/YoshinoriKobayashi/SwiftToolTrick/tree/main/lifecycle
質問は、僕のTwitter(@yoshiii514)で受け付けています。
学習する習慣を身につけたい、他の参加者と作業したい、アプリ開発の基本をマスターしたい、という方のために無料で学べる勉強会です。
グループにメンバー登録して頂くと、イベント開催時にメールで通知されます。
グループのメンバーとして参加する
本書「iPhoneアプリ開発集中講座」を執筆している現役エンジニア講師陣が直接に指導!
基礎、課題実習で実践力を鍛えて、オリジナルアプリ公開までチャレンジ!
充実した転職支援もあるので、エンジニアへ転職したい人にもおすすめです!
まずは、現役エンジニアに相談できる無料相談をご利用ください。