iOS UIViewControllerライフサイクルを理解する


299

を管理する正しい方法を教えてください UIViewControllerライフサイクル。

特に、私が使用する方法を知りたいのですがInitializeViewDidLoadViewWillAppearViewDidAppearViewWillDisappearViewDidDisappearViewDidUnloadおよびDisposeのためのモノタッチのメソッドUIViewControllerクラス。


OSX ViewControllerとWindowControllerに関する情報やリンクはありますか?共有してください。
Anoop Vaidya 2018年

回答:


410

これらすべてのコマンドは、ビューコントローラーをロード/表示/非表示にするときに、iOSによって適切なタイミングで自動的に呼び出されます。これらのメソッドはUIViewControllerUIViewそれ自体にではなく添付されていることに注意することが重要です。あなただけを使用してこれらの機能のいずれかを取得しませんUIView

Appleのサイトにはすばらしいドキュメントがあります。簡単に言えば:

  • ViewDidLoad-クラスを作成してxibからロードするときに呼び出されます。初期設定と1回限りの作業に最適です。

  • ViewWillAppear-ビューが表示される直前に呼び出されます。ビューが表示される前に毎回実行するフィールドや操作を非表示/表示するのに適しています。ビュー間を行き来している可能性があるため、ビューが画面に表示される直前に呼び出されます。

  • ViewDidAppear -ビューが表示された後に呼び出されます。アニメーションを開始したり、APIから外部データを読み込んだりするのに最適な場所です。

  • ViewWillDisappear/ DidDisappear-と同じ考え方ViewWillAppear/ ViewDidAppear

  • ViewDidUnload/ ViewDidDispose-Objective-Cでは、ここでクリーンアップと解放を行いますが、これは自動的に処理されるため、ここで実際に行う必要はあまりありません。


86
ViewDidLoadは1回限りの作業には使用しないでください。このテキストは少し誤解を招く可能性があります。メモリが不足しているためにビューがアンロードされ、その後再度ロードされた場合は、数回呼び出される可能性があります。
リッキーヘルゲソン2012

4
ViewDidLoadは、ビューコントローラを作成または初期化するときに実際には呼び出されません。これは、ビューコントローラーのビューに関連するビューを初めて実行するときに呼び出されます。サブビューとして追加するように、フレームを設定します。もちろん、ペン先からロードするときにも呼び出されます。
Jason Grandelli 2013年

3
ViewDidAppear-ビューが表示された後に呼び出されます-アニメーションやAPIからの外部データのロードを開始するのに最適な場所です。データの読み込みを開始するのに適しているのはなぜですか?なぜviewDidLoadをしないのですか?
アントンチキン14

1
loadDiveメソッドについてはどうでしょうか。nibがviewDidLoadの前にメモリに読み込まれたときに初めて呼び出された場合はどうでしょうか。
iHulk、2014

@chakritこれは良い点です。viewDidAppearはデータを更新するのに最適な場所です(必要な場合)。KVOについては同意しません。ユーザーが実際に表示することのないビューに望ましくない更新が発生する可能性があるためです。
アントン・チキン、2014

409

更新:ViewDidUnloadはiOS 6で廃止されたため、それに応じて回答を更新しました。

UIViewControllerライフサイクルは次のとおりです。

図で示したビューコントローラーのライフサイクル

Xamarin Native / Mono Touchを使用する利点は、ネイティブAPIを使用することです。そのため、Appleのドキュメントにあるのと同じViewControllerライフサイクルに従います。


17
viewWillLayoutSubviewsとviewDidLayoutSubviewsはこのフローチャートのどこに行くのですか?
Max_Power89 14

7
この図は不正確です。viewDidUnloadはiOS6以降廃止されました:stackoverflow.com/questions/12509102/...
occulus

2
これは確かに単に間違っています。年月が経つにつれ、SOに対する単に間違った答えのもう1つの例。コンピューティングは非常に静的ではありません。
Fattie

186

これは最新のiOSバージョン用です(Xcode 9.3、Swift 4.1で変更)。以下は、UIViewController完全なライフサイクルを作成するすべての段階です。

  • loadView()

  • loadViewIfNeeded()

  • viewDidLoad()

  • viewWillAppear(_ animated: Bool)

  • viewWillLayoutSubviews()

  • viewDidLayoutSubviews()

  • viewDidAppear(_ animated: Bool)

  • viewWillDisappear(_ animated: Bool)

  • viewDidDisappear(_ animated: Bool)

これらすべての段階について説明しましょう。

1。 loadView

このイベントは、コントローラーが管理するビューを作成/ロードします。関連するnibファイルからロードすることもUIView、nullが見つかった場合は空にすることもできます。これは、プログラムでコード内にビューを作成するのに適した場所です。

これは、サブクラスがnibを使用していない場合にカスタムビュー階層を作成する場所です。決して直接呼び出すべきではありません。プログラムでビューを作成し、ルートビューをviewプロパティに割り当てるときにのみ、このメソッドをオーバーライドします。loadViewをオーバーライドするときにスーパーメソッドを呼び出さないでください。

2。 loadViewIfNeeded

現在のビューがviewControllerまだ設定されていない場合、このメソッドはビューをロードしますが、これはiOS> = 9.0でのみ使用できることを覚えておいてください。したがって、iOS 9.0未満をサポートしている場合は、それが問題になるとは思わないでください。

まだ設定されていない場合は、ビューコントローラーのビューを読み込みます。

3。 viewDidLoad

このviewDidLoadイベントは、ビューが作成されてメモリに読み込まれたときにのみ呼び出されますが、ビューの境界はまだ定義されていません。これは、View Controllerが使用するオブジェクトを初期化するのに適した場所です。

ビューが読み込まれた後に呼び出されます。コードで作成されたビューコントローラーの場合、これは-loadViewの後です。nibからアーカイブ解除されたView Controllerの場合、これはビューが設定された後です。

4。 viewWillAppear

このイベントは、 viewController、ビューが画面に表示されるたびにします。このステップでは、ビューには境界が定義されていますが、方向は設定されていません。

ビューが表示される直前に呼び出されます。デフォルトでは何もしません。

5。 viewWillLayoutSubviews

これは、境界が確定されるライフサイクルの最初のステップです。制約または自動レイアウトを使用していない場合は、おそらくここでサブビューを更新する必要があります。これはiOS> = 5.0でのみ使用できます。したがって、iOS 5.0未満をサポートしている場合は、それが問題になるとは思わないでください。

ビューコントローラーのビューのlayoutSubviewsメソッドが呼び出される直前に呼び出されます。サブクラスは必要に応じて実装できます。デフォルトはnopです。

6。 viewDidLayoutSubviews

このイベントは、サブビューが設定されたことをビューコントローラーに通知します。設定後にサブビューに変更を加えるのに最適な場所です。これはiOS> = 5.0でのみ使用できます。したがって、iOS 5.0未満をサポートしている場合は、それが問題になるとは思わないでください。

ビューコントローラーのビューのlayoutSubviewsメソッドが呼び出された直後に呼び出されます。サブクラスは必要に応じて実装できます。デフォルトはnopです。

7。 viewDidAppear

viewDidAppearビューの後にイベントが発生しますが、画面上に提示されます。このため、バックエンドサービスまたはデータベースからデータを取得するのに適しています。

ビューが画面に完全に移行したときに呼び出されます。デフォルトでは何もしません

8。 viewWillDisappear

このviewWillDisappearイベントviewControllerは、presentedのビューが他のの後ろに隠れたり、閉じたり、隠れたり、隠れたりする直前に発生しviewControllerます。これは、ネットワーク呼び出しを制限したり、タイマーを無効にしたり、それにバインドされているオブジェクトを解放したりするのに適した場所ですviewController

ビューが閉じられた、カバーされた、または非表示になったときに呼び出されます。

9。 viewDidDisappear

これは、presentedのビューがviewController非表示、非表示、カバー、または非表示になった直後にこのイベントが発生するため、誰でも対処できるライフサイクルの最後のステップです。

ビューが閉じられた、カバーされた、または非表示になった後に呼び出されます。デフォルトでは何もしません

今どおりアップルあなたは、このメソッドを実装しているときに呼び出すために覚えておく必要がありsuper、その特定のメソッドの実装を。

UIViewControllerをサブクラス化する場合、NIBを使用していない場合でも、このメソッドのスーパー実装を呼び出す必要があります。(便宜上、デフォルトのinitメソッドがこれを行い、このメソッドの引数の両方にnilを指定します。)指定されたNIBで、ファイルの所有者プロキシのクラスは、ビューアウトレットを使用してビューコントローラサブクラスに設定する必要があります。メインビューに接続されています。nil nib名でこのメソッドを呼び出すと、このクラスの-loadViewメソッドは、ビューコントローラーのクラスと同じ名前のNIBをロードしようとします。そのようなNIBが実際に存在しない場合は、が呼び出される-setView:-viewに呼び出すか、-loadViewメソッドをオーバーライドしてプログラムでビューを設定する必要があります。

これがお役に立てば幸いです。ありがとう。

更新 -@ThomasWがコメント内をポイントしviewWillLayoutSubviewsviewDidLayoutSubviewsテーブルビューまたはコレクションビューのセルがロードされたときに、メインビューのサブビューは、例えば、ロードされたときにも、他の時に呼び出されます。

UPDATE -として@Mariaは内部コメントを指摘し、の説明がloadView更新されました


6
viewWillLayoutSubviewsまたviewDidLayoutSubviews、メインビューのサブビューが読み込まれるとき、たとえばテーブルビューまたはコレクションビューのセルが読み込まれるときなどにも呼び出されます。
ThomasW

この回答には誤解を招く誤解があります。loadView()は常に呼び出されます。IBで作成されたコントローラーのビューでは、オーバーライドされるべきではありません。
マリア

@マリア改善できると思われる場合は、先に進んで回答を編集してください。ありがとう。
onCompletion 2018年

デフォルトでは、何も問題はありませんviewWillAppear viewDidAppear viewDidDisappear。ある時点でスーパーを呼び出す必要があります。
Mick

47

iOS 10,11 (Swift 3.1、Swift 4.0)

よると、UIViewControllerUIKit、開発者、

1. loadView()

これは、サブクラスがnibを使用しない場合にカスタムビュー階層を作成する場所です。決して直接呼び出すべきではありません。

2. loadViewIfNeeded()

まだ設定されていない場合は、ビューコントローラーのビューを読み込みます。

3. viewDidLoad()

ビューが読み込まれた後に呼び出されます。コードで作成されたビューコントローラーの場合、これは-loadViewの後です。nibからアーカイブ解除されたView Controllerの場合、これはビューが設定された後です。

4. viewWillAppear(_ animated:Bool)

ビューが表示される直前に呼び出されます。デフォルトでは何もしません

5. viewWillLayoutSubviews()

ビューコントローラーのビューのlayoutSubviewsメソッドが呼び出される直前に呼び出されます。サブクラスは必要に応じて実装できます。デフォルトでは何もしません。

6. viewDidLayoutSubviews()

ビューコントローラーのビューのlayoutSubviewsメソッドが呼び出された直後に呼び出されます。サブクラスは必要に応じて実装できます。デフォルトでは何もしません。

7. viewDidAppear(_ animated:Bool)

ビューが画面に完全に移行したときに呼び出されます。デフォルトでは何もしません

8. viewWillDisappear(_ animated:Bool)

ビューが閉じられた、カバーされた、または非表示になったときに呼び出されます。デフォルトでは何もしません

9. viewDidDisappear(_ animated:Bool

ビューが閉じられた、カバーされた、または非表示になった後に呼び出されます。デフォルトでは何もしません

10. viewWillTransition(サイズ:CGSize、コーディネーター:UIViewControllerTransitionCoordinator)

ビューが移行中のときに呼び出されます。

11. willMove(toParentViewController parent:UIViewController?)

12. didMove(toParentViewController parent:UIViewController?)

これら2つのメソッドは、子サブコントローラー間で遷移するときにコンテナーサブクラスが呼び出すパブリックです。それらがオーバーライドされる場合、オーバーライドは必ずスーパーを呼び出す必要があります。

子が親から削除されている場合、これらのメソッドの両方の親引数はnilです。それ以外の場合は、新しい親View Controllerと同じです。

13. didReceiveMemoryWarning()

親アプリケーションがメモリ警告を受け取ったときに呼び出されます。iOS 6.0では、デフォルトでビューがクリアされなくなりました。


2
stackoverflowがこのスレッド全体からすべての間違った不完全な回答を削除しないことは本当に本当に残念です。あなたの答えは、メソッド呼び出しに関しては完全なようですので、私はあなたの答えが正しいと仮定し、それで動作します。
Logicsaurus Rex

何をしているnibの下で述べたようにloadView
ペトルスセロン2018

2
@LogicsaurusRex同意する。SOが質問に重複または保護のマークを付けるのと同じように、回答を古いものまたは古い
rmp251

上記のポイント5は間違っています。viewWillLayoutSubviews()ViewControllerのビューオブジェクトがそのlayoutSubviews()メソッドを呼び出す前に呼び出されます
williamukoh

28

iOS 6以降。新しい図は次のとおりです。

ここに画像の説明を入力してください


1
そのビューを「A」と呼びます。「A」が消える間に表示される2番目のビュー「B」を考えてみます。「B.viewWillAppear」は「A.viewDidDisappear」の前または後ですか?また、これら2つの順序が変わる状況はありますか?
ToolmakerSteve 2016

新しいビューの(B)willApearがdisAppearsの前に呼び出されるようです。2番目の質問について。調査するために少し時間が必要です。
2016

21

UIViewControllerのライフサイクルを担当するメソッドに集中しましょう。

  • 作成:

    - (void)init

    - (void)initWithNibName:

  • ビューの作成:

    - (BOOL)isViewLoaded

    - (void)loadView

    - (void)viewDidLoad

    - (UIView *)initWithFrame:(CGRect)frame

    - (UIView *)initWithCoder:(NSCoder *)coder

  • ビューステートの変更の処理:

    - (void)viewDidLoad

    - (void)viewWillAppear:(BOOL)animated

    - (void)viewDidAppear:(BOOL)animated

    - (void)viewWillDisappear:(BOOL)animated

    - (void)viewDidDisappear:(BOOL)animated

    - (void)viewDidUnload

  • メモリ警告処理:

    - (void)didReceiveMemoryWarning

  • 割り当て解除

    - (void)viewDidUnload

    - (void)dealloc

UIViewControllerのライフサイクル図

詳細については、UIViewController Class Referenceをご覧ください。


19

メソッドviewWillLayoutSubviewsviewDidLayoutSubviewsは図には記載されていませんが、これらはとの間viewWillAppearで呼び出されviewDidAppearます。それらは複数回呼び出すことができます。


また、テーブルビューやコレクションビューのセルが読み込まれたときなど、メインビューのサブビューが読み込まれたときにも呼び出されます。
ThomasW 2016

16

Haiderの答えはiOS 6より前の場合は正しいです。ただし、iOS 6以降は、viewDidUnloadとviewWillUnloadが呼び出されることはありません。ドキュメントの状態:「ビューは、メモリ不足の条件の下でパージし、このメソッドが呼び出されることはありませんので、されなくなりました。」


ViewWillDisappear、ViewDidDisappear、Disposeにブレークポイントを設定してみました。しかし、PresentViewController()メソッドでナビゲートしたときに、それらのどれも呼び出されませんでした。その理由は何でしょうか?
Sreeraj 2014

1
リンクが機能しない...では、OSはメモリ不足のもとで何をするのでしょうか。
息子

それらをディスクに保存しますか?
Ian Warburton 2016

16

ここには、古くて不完全な情報がたくさんあります。以下のためのiOS 6以降のみ:

  1. loadView[a]
  2. viewDidLoad[a]
  3. viewWillAppear
  4. viewWillLayoutSubviews 境界が初めて確定される
  5. viewDidLayoutSubviews
  6. viewDidAppear
  7. * viewWillLayoutSubviews[b]
  8. * viewDidLayoutSubviews[b]

脚注:

() -手動時に、あなたのビューをnilをした場合didReceiveMemoryWarningloadViewそしてviewDidLoad再び呼び出されます。これはデフォルトであり、loadViewかつviewDidLoad唯一のビューコントローラのインスタンスごとに一度呼び出されます。

(b)追加の0回以上呼び出されることがあります。


1
viewWillLayoutSubviewsまたviewDidLayoutSubviews、メインビューのサブビューが読み込まれるとき、たとえばテーブルビューまたはコレクションビューのセルが読み込まれるときなどにも呼び出されます。
ThomasW

11

公式ドキュメントでの状態遷移の説明: https //developer.apple.com/library/ios/documentation/uikit/reference/UIViewController_Class/index.html

この画像は、さまざまなビュー「will」と「did」のコールバックメソッド間の有効な状態遷移を示しています

有効な状態遷移:


取得元:https : //developer.apple.com/library/ios/documentation/uikit/reference/UIViewController_Class/Art/UIViewController Class Reference_2x.png


0

Appleのドキュメントに従って— iOSアプリ(Swift)の開発を開始します— View Controllerを操作します— View Controllerのライフサイクルを理解します

viewDidLoad()-ビューコントローラーのコンテンツビュー(ビュー階層の最上位)が作成され、ストーリーボードから読み込まれるときに呼び出されます。…このメソッドを使用して、View Controllerに必要な追加のセットアップを実行します。

viewWillAppear()-ビューコントローラーのコンテンツビューがアプリのビュー階層に追加される直前に呼び出されます。このメソッドを使用して、コンテンツビューが画面に表示される前に発生する必要がある操作をトリガーします

viewDidAppear()-ビューコントローラーのコンテンツビューがアプリのビュー階層に追加された直後に呼び出されます。このメソッドを使用して、データのフェッチやアニメーションの表示など、ビューが画面に表示されたらすぐに実行する必要のある操作をトリガーします。

viewWillDisappear()-ビューコントローラーのコンテンツビューがアプリのビュー階層から削除される直前に呼び出されます。このメソッドを使用して、変更のコミットやファーストレスポンダステータスの辞任などのクリーンアップタスクを実行します。

viewDidDisappear()-ビューコントローラーのコンテンツビューがアプリのビュー階層から削除された直後に呼び出されます。このメソッドを使用して、追加のティアダウンアクティビティを実行します。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.