在 iOS5中视图控制器控制是如何工作的?

在 WWDC 2011年102会议上,苹果引入了视图控制器控制,这是能够创建自定义视图控制器容器,类似于 UITabBarControllerUINavigationController,等等。

我把这些例子看了好几遍。与这种模式相关的方法有很多,但要准确地找出它们有点困难。我要在这里发布我认为正在发生的事情,看看社区是否会证实或否认我的怀疑。

场景1: 从没有父视图转移到新的父视图控制器

[vc willMoveToParentViewController:self];
[self addChildViewController:vc];
[self.view addSubview:vc.view]; // or something like this.
[vc didMoveToParentViewController:self];

前两行必须按照给定的顺序出现,还是可以颠倒过来?

场景2: 从父视图控制器移动到没有父视图控制器

[vc willMoveToParentViewController:nil];
[vc.view removeFromSuperview];
[vc removeFromParentViewController];

是否也需要调用 [vc didMoveToParentViewController:nil]?在这个场景中的会话102不是我干的中的例子,但是我不知道这是否是一个遗漏。

场景3: 从一个父视图控制器移动到另一个父视图控制器

这可能以下列方式发生,因为将封装每个父视图控制器中的逻辑。

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

问题

我的主要问题是: 一般来说,视图控制器包含应该是这样工作的吗?上面给出的力学原理正确吗?

在调用 addChildViewController之前有必要调用 willMoveToParentViewController吗?对我来说,这似乎是合乎逻辑的顺序,但是这真的有必要吗?

在调用 removeFromParentViewController之后是否需要调用 didMoveToParentViewController:nil

53611 次浏览

The UIViewController docs are pretty clear on when and when not to call willMove/didMove methods. Check out the "Implementing a Container View Controller" documentation.

The docs say, that if you do not override addChildViewController, you do not have to call willMoveToParentViewController: method. However you do need to call the didMoveToParentViewController: method after the transition is complete. "Likewise, it is is the responsibility of the container view controller to call the willMoveToParentViewController: method before calling the removeFromParentViewController method. The removeFromParentViewController method calls the didMoveToParentViewController: method of the child view controller."

Also, there is an example worked out here and sample code here.

Good Luck

This part is not correct:

[vc willMoveToParentViewController:self];
[self addChildViewController:vc];
[self.view addSubview:vc.view]; // or something like this.
[vc didMoveToParentViewController:self];

According to the docs:

When your custom container calls the addChildViewController: method, it automatically calls the willMoveToParentViewController: method of the view controller to be added as a child before adding it.

So you don't need the [vc willMoveToParentViewController:self] call. It is done automatically when you call [self addChildViewController:vc]. Here's the code sample again:

[self addChildViewController:vc];
// [vc willMoveToParentViewController:self] called automatically
[self.view addSubview:vc.view]; // or something like this.
[vc didMoveToParentViewController:self];

For removing view controllers:

The removeFromParentViewController method automatically calls the didMoveToParentViewController: method of the child view controller after it removes the child.

Presumably this call is [oldVC didMoveToParentViewController:nil].

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