在 WWDC 2011 Session 102 中,Apple 引入了 View Controller Containment,这是创建自定义视图控制器容器的能力,类似于 UITabBarController
、UINavigationController
等。
我看了好几遍这些例子。有很多与这种模式相关的方法,但要准确地找出它们有点困难。我将在这里发布我认为正在发生的事情,看看社区是否会证实或否定我的怀疑。
场景 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]
? Session 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
?
UIViewController
文档非常清楚何时以及何时不调用 willMove
/didMove
方法。查看 "Implementing a Container View Controller" 文档。
文档说,如果您不覆盖 addChildViewController
,则不必调用 willMoveToParentViewController:
方法。但是,您确实需要在转换完成后调用 didMoveToParentViewController:
方法。 “同样,容器视图控制器有责任在调用 removeFromParentViewController
方法之前调用 willMoveToParentViewController:
方法。removeFromParentViewController
方法调用子视图控制器的 didMoveToParentViewController:
方法。”
祝你好运
这部分不正确:
[vc willMoveToParentViewController:self];
[self addChildViewController:vc];
[self.view addSubview:vc.view]; // or something like this.
[vc didMoveToParentViewController:self];
当您的自定义容器调用 addChildViewController: 方法时,它会在添加视图控制器之前自动调用要添加为子视图控制器的 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];
For removing view controllers:
removeFromParentViewController 方法在移除子视图后会自动调用子视图控制器的 didMoveToParentViewController: 方法。
大概这个调用是 [oldVC didMoveToParentViewController:nil]
。
[vc willMoveToParentViewController:nil];
[vc.view removeFromSuperview];
[vc removeFromParentViewController];
// [vc didMoveToParentViewController:nil] called automatically
didMoveToParentViewController
"立即",它没有指定您实际添加子子视图的时间。我想知道是不是每个人都搞错了。在某些 Apple Docs 中是否有我们可以检查的示例?
addChildViewController
的自定义类,您确实需要在 addChildViewController
之前调用 willMoveToParentViewController
(除非您的覆盖在内部调用它)
addChildViewController
应该与didMoveToParentViewController
平衡,willMoveToParentViewController
应该与removeFromParentViewController
平衡。这正是我一直在寻找的。不知道我是如何在文档中错过它的。