概述
关键方法只有四个:
-
addChildViewController:
建立父子关系且自动调用willMoveToParentViewController:parentVC
方法; -
removeFromParentViewController:
取消父子关系,且自动调用didMoveToParentViewController:nil
; -
willMoveToParentViewController:
添加时参数为parentVC,系统自动调用,移除时参数为nil,需手动调用; -
didMoveToParentViewController:
添加时参数为parentVC,需手动调用,移除时参数为nil,系统自动调用;
添加 childVC:
步骤:
- 调用
addChildViewController:
添加子控制器到父控制器,建立关联。此时系统自动调用willMoveToParentViewController:
方法,parent 参数为父控制器; - 添加子控制器 View 到父控制器;
- 设置约束;
- 手动调用
didMoveToParentViewController:
方法,parent 参数为父控制器;
// 会自动调用[childVC willMoveToParentViewController:self]
[self addChildViewController:childVC];
// 添加view
[self.view addSubview: childVC.view];
// 设置约束
[childVC.view mas_remakeConstraints:^(MASConstraintMaker *make) {
make.edges.equalTo(self.view);
}];
// 手动调用willMoveToParentViewController方法
[childVC didMoveToParentViewController:self];
官方文档代码示例:
移除 childVC:
步骤:
- 手动调用
willMoveToParentViewController
方法,parent 参数为nil,表示移除操作; - 移除子控制器的 View;
- 调用
removeFromParentViewController:
移除子控制器,取消关联,该方法会自动调用didMoveToParentViewController
,parent 参数为nil,表示移除操作;
// 手动调用willMoveToParentViewController方法
[vc willMoveToParentViewController:nil];
// 移除子控制器的view
[vc.view removeFromSuperview];
// 取消关联,会主动调用didMoveToParentViewController:
[vc removeFromParentViewController];
官方文档代码:
总结
- didMoveToParentViewController 和 willMoveToParentViewController 方法本质是自定义容器时,对 VC 生命周期的控制;
- 这两个方法在默认情况下不调用,也不会有太大问题,不会影响到 viewWillApear、viewDidAppear 方法的自动调用;
- 但是如果自己自定义 VC 的容器,比如 nav 就是一种 VC 容器。这种情况下, didMoveToParentViewController 和 willMoveToParentViewController 会涉及到一些自定义的逻辑,比如状态的初始化、view 的初始化等,此时就必须严格按照 apple 建议的流程来,否容易出问题;
- 本质上是一种流程规范和 parent 管理 child 的设计思想;