addChildViewController实际上做了什么?
我只是第一次进入iOS开发,我不得不做的第一件事是实现一个自定义的容器视图控制器 - 让我们称之为SideBarViewController
- 它可以将多个可能的子视图控制器中的哪一个它显示,几乎完全像一个标准的标签栏控制器。 (这几乎是一个标签栏控制器,但有一个可隐藏的侧面菜单,而不是标签栏。)
根据Apple文档中的说明,每当向容器中添加一个子ViewController时,我都会调用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
在这里做什么,并且我意识到我不知道。 除了在.childViewControllers
数组中粘贴新的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:
但它没有提供任何关于它所谈论的“事件”或“预期的遏制行为”是什么的线索,或者为什么(甚至是何时)调用这些方法是'必需的'。
Apple文档的“Custom Container View Controllers”部分中的自定义容器视图控制器的示例都调用此方法,所以我认为它的作用不仅仅是将子ViewController弹出到数组上,而且还有一些重要用途,但我无法确定出于什么目的。 这种方法做什么,为什么我应该叫它?
我也在想这个问题。 我观看了WWDC 2011视频中的Session 102和View Controller先生Bruce D. Nilo,他说:
viewWillAppear:
, viewDidAppear:
等与addChildViewController:
无关addChildViewController:
。 所有addChildViewController:
确实是说“这个视图控制器是那个视图的子视图”,它与视图外观无关。 它们被调用时与视图移入和移出窗口层次结构时相关联。
所以看起来,调用addChildViewController:
做的很少。 呼叫的副作用是重要的部分。 它们来自parentViewController
和childViewControllers
关系。 以下是我所知道的一些副作用:
transitionFromViewController:toViewController:…
两个VC需要具有相同的父级 navigationController
, tabBarController
等属性 我认为一个例子胜过千言万语。
我正在研究一个图书馆应用程序,并希望显示一个很好的记事本视图,当用户想要添加记事时,该视图就会出现。
在尝试了一些解决方案之后,我最终创建了自己的定制解决方案来显示记事本。 因此,当我想要显示记事本时,我创建了一个NotepadViewController
的新实例,并将它的根视图作为子视图添加到主视图中。 到现在为止还挺好。
然后我注意到记事本图像在横向模式下部分隐藏在键盘下。
所以我想改变记事本图像并将其改变。 为此,我在willAnimateRotationToInterfaceOrientation:duration:
方法中编写了适当的代码,但是当我运行应用程序时什么也没有发生! 调试后,我注意到没有任何UIViewController
的旋转方法实际上是在NotepadViewController
中NotepadViewController
。 只有主视图控制器中的那些方法正在被调用。
为了解决这个问题,我需要在主视图控制器中调用NotepadViewController
所有方法。 这将很快使事情变得复杂,并在应用程序中的无关组件之间创建额外的依赖关系。
在引入子视图控制器的概念之前,这是过去的事情。 但现在,您只需将addChildViewController
到主视图控制器,一切都将按预期工作,而无需进行任何手动工作。
编辑:有两类事件被转发给子视图控制器:
1-外观方法:
- viewWillAppear:
- viewDidAppear:
- viewWillDisappear:
- viewDidDisappear:
2-旋转方法:
- willRotateToInterfaceOrientation:duration:
- willAnimateRotationToInterfaceOrientation:duration:
- didRotateFromInterfaceOrientation:
您还可以通过覆盖shouldAutomaticallyForwardRotationMethods
和shouldAutomaticallyForwardAppearanceMethods
来自动控制要转发的事件类别。
-[UIViewController addChildViewController:]
只在视图控制器(父级)想要引用的视图控制器数组中添加传入的视图控制器。 实际上你应该在屏幕上添加这些viewController的视图,把它们作为另一个视图的子视图添加(例如parentViewController的视图)。 在Interface Builder中还有一个便利对象,用于在Storyboard中使用childrenViewControllers。
以前,为了保持其他视图控制器的引用,您必须在@properties中手动引用它们。 拥有诸如childViewControllers
类的childViewControllers
属性以及parentViewController
是一种便捷的方式来管理此类交互并构建组合的viewController,例如您在iPad应用上找到的UISplitViewController。
此外,childrenViewControllers还会自动接收父级收到的所有系统事件:-viewWillAppear,-viewWillDisappear等。以前,您应该在“childrenViewControllers”上手动调用此方法。
而已。
链接地址: http://www.djcxy.com/p/58355.html上一篇: What does addChildViewController actually do?
下一篇: Where to initialize something ONCE in a UIViewController