SideBarViewController
,它可以交换显示多个可能的子视图控制器,就像标准的Tab Bar Controller一样。 (它基本上是一个带有可隐藏侧边菜单而不是选项卡栏的Tab Bar Controller。)按照Apple文档中的说明,每当我向容器添加一个子视图控制器时,都会调用
addChildViewController
。我的代码用于交换当前由SideBarViewController
显示的子视图控制器如下:- (void)showViewController:(UIViewController *)newViewController {
UIViewController* oldViewController = [self.childViewControllers
objectAtIndex:0];
[oldViewController removeFromParentViewController];
[oldViewController.view removeFromSuperview];
newViewController.view.frame = CGRectMake(
0, 0, self.view.frame.size.width, self.view.frame.size.height
);
[self addChildViewController: newViewController];
[self.view addSubview: newViewController.view];
}
然后我开始尝试弄清楚这里的
addChildViewController
到底是做什么的,但我意识到我不知道。除了将新的ViewController
添加到.childViewControllers
数组中,它似乎对任何事情都没有影响。即使我从未调用addChildViewController
,从子控制器的视图到故事板上设置的子控制器的操作和插座仍然可以正常工作,我无法想象它还可能影响什么。
实际上,如果我重写我的代码而不调用addChildViewController
,并且看起来像这样...
- (void)showViewController:(UIViewController *)newViewController {
// Get the current child from a member variable of `SideBarViewController`
UIViewController* oldViewController = currentChildViewController;
[oldViewController.view removeFromSuperview];
newViewController.view.frame = CGRectMake(
0, 0, self.view.frame.size.width, self.view.frame.size.height
);
[self.view addSubview: newViewController.view];
currentChildViewController = newViewController;
}
... 那么就目前而言,我的应用程序仍然可以正常工作!
苹果文档并没有详细解释addChildViewController
的作用或者我们为什么需要调用它。在UIViewController
类参考中,关于这个方法的相关描述如下:
将给定的视图控制器添加为子控制器。 ... 此方法仅适用于自定义容器视图控制器的实现。如果您重写此方法,则必须在您的实现中调用super。
此外,同一页之前有一段描述:
你的容器视图控制器必须在将子视图的根视图添加到视图层次结构之前,将子视图控制器与自身关联。这样iOS才能正确地将事件路由到子视图控制器和这些控制器管理的视图。同样,在从其视图层次结构中删除子视图的根视图后,它应该断开该子视图控制器与自身的联系。为了建立或断开这些关联,您的容器调用基类定义的特定方法。这些方法不是容器类的客户端调用的,它们仅由容器的实现使用以提供预期的包含行为。以下是您可能需要调用的关键方法: addChildViewController: removeFromParentViewController willMoveToParentViewController: didMoveToParentViewController:
但是,它并没有提供任何线索,解释它所说的“事件”或“预期的包含行为”是什么,也没有解释为什么(甚至何时)调用这些方法是“必要的”。
苹果文档中“自定义容器视图控制器”部分的自定义容器视图控制器示例都调用此方法,因此我假设它除了将子视图控制器弹出数组之外还具有某些重要目的,但我无法确定该目的是什么。这个方法是做什么的,为什么我应该调用它?