iOS早在iOS5的时候为了解耦、更加清晰的处理页面View的逻辑,UIViewController
提供了addChildViewController
方法,将ViewController
作为容器处理视图控制器的切换,将比较复杂的UI使用子ViewController
来管理。
项目中使用:
在我们项目的APP首页的实现中使用到了,首页内容展示位推荐分类菜单,以及每个菜单下的内容展示,不同的分类下的内容view
展示的UI多样化。
相关方法:
///子视图控制器数组
@property(nonatomic,readonly) NSArray *childViewControllers
///向父VC中添加子VC
- (void)addChildViewController:(UIViewController *)childController
///将子VC从父VC中移除
- (void) removeFromParentViewController
///fromViewController 当前显示在父视图控制器中的子视图控制器
///toViewController 将要显示的姿势图控制器
///duration 动画时间
/// options 动画效果(渐变,从下往上等等,具体查看API)
///animations 转换过程中得动画
///completion 转换完成
- (void)transitionFromViewController:(UIViewController *)fromViewController toViewController:(UIViewController *)toViewController duration:(NSTimeInterval)duration options:(UIViewAnimationOptions)options animations:(void (^ __nullable)(void))animations completion:(void (^ __nullable)(BOOL finished))completion
///当向父VC添加子VC之后,该方法会自动调用;
- (void)willMoveToParentViewController:(UIViewController *)parent
///从父VC移除子VC之后,该方法会自动调用
- (void)didMoveToParentViewController:(UIViewController *)parent
如何使用?:
- 如果在view上添加的只是简单的控件的话,那么使用addSubView添加到父ViewController上;
- 如果子视图是比较复杂的视图集合,功能丰富,就选择使用
addChildViewController
来添加新的子ViewController
,但也需要通过addSubview
将子ViewController
的view
添加到父视图的视图层级中; - iOS5之后使用
addChildViewController
时的原则,我们在使用addSubview的时候,同时调用addChildViewController
方法将subView对应的viewController
也加到当前viewController
的管理中; - 对于那些不需要显示的
subView
,只需通过addChildViewController
把subVC
添加到父控制器中,需要显示时再调用transitionFromViewController
方法将其显示出来; - 当收到系统的
Memory Warning
的时候,系统也会自动把当前没有显示的subview
销毁掉 掉,以节省内存; - 优点:
系统方法解释:
- addChildViewController
注意:调用addChildViewController后会自动调用willMoveToParentViewController:superVC方法;
- removeFromParentViewController
注意:调用removeFromParentViewControlle后会调用didMoveToParentViewController:nil方法
- willMoveToParentViewController
- didMoveToParentViewController
代码展示:
- 添加子VC
//自动调用,可以省略
//[childVC willMoveToParentViewController: superVC];
[superVC addChildViewController:childVC];
[superVC.view addSubview:childVC.view];
[childVC didMoveToParentViewController:superVC];
- 删除子VC
[childVC willMoveToParentViewController];
[childVC removeFromParentViewController];
//自动调用,可以省略
//[childVC didMoveToParentViewController:nil];
- 切换子VC
[self addChildViewController:newController];
[self transitionFromViewController:oldController toViewController:newController duration:1.5f options:UIViewAnimationOptionCurveEaseOut animations:^{
} completion:^(BOOL finished) {
if (finished) {
[newController didMoveToParentViewController:self];
[oldController willMoveToParentViewController:nil];
[oldController removeFromParentViewController];
self.currentVC = newController;
}
else{
self.currentVC = oldController;
}
}];
总结:
-
addChildViewController
向父视图控制器中添加子视图控制器时,添加之后自动调用willMoveToParentViewController
,需要手动调用didMoveToParentViewController
; -
removeFromParentViewController
将子视图控制器从父视图控制器中移除,移除之后自动调用didMoveToParentViewController: nil
参数为nil
,需要在移除前手动调用willMoveToParentViewController
; -
transitionFromViewController:toViewController
在调用这个方法之前先调用[fromViewController willMoveToParentViewController:nil]
然后在completion
后调用[toViewController didMoveToParentViewController:self]
方法; - 在切换子视图控制器显示的时候需要保证切换的子视图控制器已经被添加到父视图控制器中;
- 当某个子视图控制器将从父视图控制器中删除时,
parent
参数为nil,即:[将被删除的VC willMoveToParentViewController:nil]
; - 当某个子试图控制器将加入到父视图控制器时,
parent
参数为父视图控制器,即:[将被加入的VC didMoveToParentViewController:superVC]
;
参考文献
- https://blog.csdn.net/yongyinmg/article/details/40619727
- iOS之ViewController容器篇
- 学习笔记:addChildViewController