在iOS 5之前苹果是不允许出现自定义的Container的 ,也就是说你创建的一个View Controller的view不能包含另一个View Controller的view,这对于逻辑复杂的界面来说,不易于功能拆分。也许曾经你为了某个公用的显示逻辑,直接将某个View Controller的view添加到另一个View Controller的view上,然后发现可以正常显示和使用,但实际上这种行为是非常危险的。
实现一个Custom Container View Controller并不是一个简单的事情,主要分为两个阶段:父子关系的建立以及父子关系的解除。如果pVC将cVC的view添加为自己的subview,那么cVC必须为pVC的Child View Controller,而反过来则不一定成立,比如UINavigationController,一个View Controller被push进来后便和navigationController建立父子关系了,但是只有最上面的View Controller 是显示着的,底下的View Controller的view则被移出了容器的view的显示层级,当一个View Controller被pop之后,便和navigationController解除了父子关系了。
//
展示一个名为
content
的
child view controller
:
- ( void )displayContentController: ( UIViewController *)content {
[ self addChildViewController:content]; //1
content.view.frame =self.view.bounds; //2
[self.viewaddSubview:content.view]; //3
[content didMoveToParentViewController:self]; //4
- ( void )displayContentController: ( UIViewController *)content {
[ self addChildViewController:content]; //1
content.view.frame =self.view.bounds; //2
[self.viewaddSubview:content.view]; //3
[content didMoveToParentViewController:self]; //4
}
1.将content添加为child view controller,addChildViewController:接口建立了逻辑上的父子关系,子可以通过parentViewController,访问其父VC,addChildViewController:接口的逻辑中会自动调用 [content willMoveToParentViewController:self];
2.
设置VC这个controller里的根view的frame。
3.建立父子关系后,便是将content的view加入到父VC的view hierarchy上,同时要决定的是 content的view显示的区域范围。
4.调用child的 didMoveToParentViewController: ,以通知child,完成了父子关系的建立
//
移除一个
child view controller
:
- ( void )hideContentController: ( UIViewController *)content {
[content willMoveToParentViewController : nil ]; //1
[content. view removeFromSuperview]; //2
[content removeFromParentViewController]; //3
- ( void )hideContentController: ( UIViewController *)content {
[content willMoveToParentViewController : nil ]; //1
[content. view removeFromSuperview]; //2
[content removeFromParentViewController]; //3
}
1.通知child,即将解除父子关系,从语义上也可以看出 child的parent即将为nil
2.将child的view从父VC的view的hierarchy中移除
3.通过removeFromParentViewController的调用真正的解除关系,removeFromParentViewController会自动调用 [content didMoveToParentViewController:nil]
遇到的问题:
在
viewDidLoad 方法里 addChildViewController 之后frame不对
解决办法:
用
super
.
view
.
bounds来确定frame大小。
_couponReturnView = [[ UCFCouponReturn alloc ] initWithNibName : @"UCFCouponReturn" bundle : nil ];
_couponReturnView . status = @"1" ;
_couponReturnView . view . frame = CGRectMake ( 0 , 44 , CGRectGetWidth ( super . view . bounds ), ScreenHeight - 108 );
// _couponReturnView . view . autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight ;
[ self addChildViewController : _couponReturnView ];
参考文章: