web-dev-qa-db-ja.com

View Controller ContainmentはiOS 5でどのように機能しますか?

WWDC 2011セッション102では、Apple View Controller Containmentが導入されました。これは、UITabBarControllerUINavigationController、および好む。

例を何度か見ました。このパターンに関連付けられたメソッドは多数ありますが、それらを正確に把握するのは少し困難でした。私はここで私が起こっていると思うことを投稿し、コミュニティが私の疑いを確認するか否かを確認します。

シナリオ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を呼び出す必要がありますか?

107
Gregory Higley

UIViewControllerのドキュメントは、willMove/didMoveメソッドをいつ、どのタイミングで呼び出さないかを明確にしています。 "Container View Controllerの実装" ドキュメントをご覧ください。

ドキュメントでは、addChildViewControllerをオーバーライドしない場合、willMoveToParentViewController:メソッドを呼び出す必要はないと述べています。ただし、移行の完了後にdidMoveToParentViewController:メソッドを呼び出す必要があります。 「同様に、removeFromParentViewControllerメソッドを呼び出す前にwillMoveToParentViewController:メソッドを呼び出すのは、コンテナView Controllerの責任です。removeFromParentViewControllerメソッドは、didMoveToParentViewController:メソッドを呼び出します子View Controller。」

また、解決済みの例 here とサンプルコード here があります。

幸運を

73
timthetoolman

この部分は正しくありません:

[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];

View Controllerを削除する場合:

RemoveFromParentViewControllerメソッドは、子を削除した後、子View ControllerのdidMoveToParentViewController:メソッドを自動的に呼び出します。

おそらく、この呼び出しは[oldVC didMoveToParentViewController:nil]です。

[vc willMoveToParentViewController:nil];
[vc.view removeFromSuperview];
[vc removeFromParentViewController];
// [vc didMoveToParentViewController:nil] called automatically
22
nevan king