17

子视图控制器在子视图控制器的实现中被以下代码删除:

- (void)commandFinishVC
{
    [ self.view removeFromSuperview];
    [ self removeFromParentViewController ];
}

子视图控制器及其视图已成功删除,但是如何通知父级呢?-viewDidDisappear 未被调用并且 -viewDidUnload 已被弃用。

从我可以找到的示例中,始终假定父视图控制器是指定要删除的子项的事件的发起者,但是(对我而言)子项在其完成逻辑中应该是自主的。

是否应该通过使用 self.parentViewController 属性并在父视图控制器中使用类似以下内容来调用删除方法?

- (void)commandFinishVC
{
    [ childVC.view removeFromSuperview];
    [ childVC removeFromParentViewController ];
}
4

1 回答 1

26

是的,您的父控制器通常应该控制子控制器的添加和删除,因此您的第二种方法似乎更适用。请参阅UIViewController 类参考的实现容器视图控制器部分。

我怀疑您可以摆脱以前的方法,即孩子正在移除自己,但苹果在他们的文档中是一致的,并且关于实现 UIViewController包含的 WWDC 2011 会议说容器控制器承担管理孩子的责任。

因此,在回答您关于孩子如何通知父母它已被移除的问题时,没有既定的协议。但这并不奇怪,因为假定父母将启动此过程。如果孩子需要启动这个过程,文档建议父母应该有一个公共 API 来管理子控制器。

因此,虽然没有孩子通知父母的协议,但是有一个已发布的 API,父母控制器通过该 API 通知孩子他们已被移动/移除。具体来说,当父控制器移除子控制器时,它应该调用willMoveToParentViewController. 该文档明确指出我们必须执行此通知:

如果你正在实现自己的容器视图控制器,它必须在调用方法willMoveToParentViewController:之前调用子视图控制器的removeFromParentViewController方法......

因此,正如View Controller Programming Guide的添加和删除子部分中所讨论的,在删除子时,我们应该:

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

毫不奇怪,文档didMoveToParentViewController同样明确:添加子控制器时,必须didMoveToParentViewController在动画/过渡(如果有)完成时调用。我不知道如果我们不调用这两种通知方法会发生什么,但 Apple 表示我们必须这样做,因此这样做似乎是谨慎的。

于 2013-01-04T23:07:48.423 回答