2011-12-05 19 views
103

在WWDC 2011 Session 102中,Apple推出了View Controller Containment,它可以创建自定义视图控制器容器,类似于UITabBarControllerUINavigationController等。View Controller Containment如何在iOS 5中工作?

我多次看过这些例子。这种模式有许多相关的方法,但要弄清楚它们有点困难。我将在此发布我认为正在发生的事情,看看社区是否会证实或否认我的怀疑。

方案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

+9

问题是,当我试图添加ios5标签时,我不小心打了一个回车,即使我没有完成编辑/编辑它,也添加了帖子。我试图删除它,但后来发现我只能*投票*删除它。 –

回答

71

UIViewController文档很清楚何时何时不打电话给willMove/didMove方法。查看"Implementing a Container View Controller"文档。

该文档说,如果您不覆盖addChildViewController,则不必调用willMoveToParentViewController:方法。但是,在转换完成后,您确实需要调用didMoveToParentViewController:方法。 “同样,在调用removeFromParentViewController方法之前,容器视图控制器负责调用willMoveToParentViewController:方法。removeFromParentViewController方法调用子视图控制器的didMoveToParentViewController:方法。

此外,还有一个例子是here和示例代码here

好运

+15

我看到了,所以'addChildViewController'应该与'didMoveToParentViewController'平衡,'willMoveToParentViewController'应该与'removeFromParentViewController'平衡。这正是我所期待的。不知道我是如何在文档中错过的。 –

+0

为什么不呢?为什么你不必调用willMoveToParentViewController,但是可以调用didMoveToParentViewController? –

+0

因为这就是文档所说的。苹果显然觉得我们不需要知道。 – 2012-10-15 14:55:22

21

这部分是不正确的:

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

According to the docs:

当您的自定义容器调用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 
+0

它看起来,如果不这样做,即使它似乎工作,presentationViewController presentationViewController没有设置presentViewController。 – Adrian

+0

文档在调用addChildViewController:方法之后说“调用'didMoveToParentViewController'”**立即**,它并没有指定实际添加子子视图的时间。我想知道是否每个人都有这个错误。我们可以检查一些Apple文档中是否有一个例子? – Robert

+0

注意:如果您正在移动的项目是一个自定义类,并带有重载的“addChildViewController”,您需要在addChildViewController之前调用'willMoveToParentViewController'(除非您的覆盖在内部调用它) – bunkerdive

相关问题