WWDC 2011セッション102では、Apple View Controller Containmentが導入されました。これは、UITabBarController
、UINavigationController
、および好む。
例を何度か見ました。このパターンに関連付けられたメソッドは多数ありますが、それらを正確に把握するのは少し困難でした。私はここで私が起こっていると思うことを投稿し、コミュニティが私の疑いを確認するか否かを確認します。
シナリオ1:親なしから新しい親View Controllerへの移動
[vc willMoveToParentViewController:self];
[self addChildViewController:vc];
[self.view addSubview:vc.view]; // or something like this.
[vc didMoveToParentViewController:self];
最初の2行は指定された順序で発生する必要がありますか、それとも逆にすることができますか?
シナリオ2:親View Controllerから親View Controllerなしへの移行
[vc willMoveToParentViewController:nil];
[vc.view removeFromSuperview];
[vc removeFromParentViewController];
[vc didMoveToParentViewController:nil]
を呼び出す必要もありますか?セッション102の例はこのシナリオではこれを行いませんでしたが、それが省略であったかどうかはわかりません。
シナリオ3:ある親View Controllerから別の親への移動
各親View Controllerのロジックがカプセル化されるため、これはおそらく次のように発生します。
// In the old parent
[vc willMoveToParentViewController:nil];
[vc.view removeFromSuperview];
[vc removeFromParentViewController];
// In the new parent
[vc willMoveToParentViewController:self];
[self addChildViewController:vc];
[self.view addSubview:vc.view];
[vc didMoveToParentViewController:self];
質問
私の主な質問は次のとおりです。これは、一般的にView Controllerのコンテインメントがどのように機能するかです。上記のメカニズムは正しいですか?
willMoveToParentViewController
を呼び出す前にaddChildViewController
を呼び出す必要がありますか?これは論理的な順序のように思えますが、厳密に必要ですか?
removeFromParentViewController
を呼び出した後にdidMoveToParentViewController:nil
を呼び出す必要がありますか?
UIViewController
のドキュメントは、willMove
/didMove
メソッドをいつ、どのタイミングで呼び出さないかを明確にしています。 "Container View Controllerの実装" ドキュメントをご覧ください。
ドキュメントでは、addChildViewController
をオーバーライドしない場合、willMoveToParentViewController:
メソッドを呼び出す必要はないと述べています。ただし、移行の完了後にdidMoveToParentViewController:
メソッドを呼び出す必要があります。 「同様に、removeFromParentViewController
メソッドを呼び出す前にwillMoveToParentViewController:
メソッドを呼び出すのは、コンテナView Controllerの責任です。removeFromParentViewController
メソッドは、didMoveToParentViewController:
メソッドを呼び出します子View Controller。」
また、解決済みの例 here とサンプルコード here があります。
幸運を
この部分は正しくありません:
[vc willMoveToParentViewController:self];
[self addChildViewController:vc];
[self.view addSubview:vc.view]; // or something like this.
[vc didMoveToParentViewController:self];
カスタムコンテナがaddChildViewController:メソッドを呼び出すと、View ControllerのwillMoveToParentViewController:メソッドが自動的に呼び出され、追加する前に子として追加されます。
したがって、[vc willMoveToParentViewController:self]
呼び出しは必要ありません。 [self addChildViewController:vc]
を呼び出すと自動的に行われます。コードサンプルは次のとおりです。
[self addChildViewController:vc];
// [vc willMoveToParentViewController:self] called automatically
[self.view addSubview:vc.view]; // or something like this.
[vc didMoveToParentViewController:self];
RemoveFromParentViewControllerメソッドは、子を削除した後、子View ControllerのdidMoveToParentViewController:メソッドを自動的に呼び出します。
おそらく、この呼び出しは[oldVC didMoveToParentViewController:nil]
です。
[vc willMoveToParentViewController:nil];
[vc.view removeFromSuperview];
[vc removeFromParentViewController];
// [vc didMoveToParentViewController:nil] called automatically