视图控制器的父-子关系

addChildViewController 优点

1.页面逻辑很清晰,相应的View对应相应的ViewController。
2.当某个子View没有显示时,将不会被Load,减少了内存的使用。
3.当内存紧张时,没有Load的View将被首先释放,优化了程序的内存释放机制。

在iOS 5.0及以后,iOS为UIViewController类添加了新的属性和方法:

@property(nonatomic,readonly) NSArray *childViewControllers
- (void)addChildViewController:(UIViewController *)childController
- (void) removeFromParentViewController
- (void)transitionFromViewController::::::
- (void)willMoveToParentViewController:(UIViewController *)parent
- (void)didMoveToParentViewController:(UIViewController *)parent

这样,就能够将一个页面中的UIViewController控制起来,而不是混乱的共用一个UIViewController,最重要的是,编程习惯的革命:
降低了功能的耦合度!

1. [父视图控制器 addChildViewController:子视图控制器];

在此,图控制器A添加了另一个图控制器B,那么A充当父视图控制器,B充当子视图控制器。父视图控制器充当了视图控制器容器的角色。当要添加的子视图控制器已经包含在视图控制器容器中,那么,相当于先从父视图控制器中删除,然后重新添加到父视图控制器中。

2. - (void)removeFromParentViewController 从父视图控制器中删除。

3.- (void)transitionFromViewController::::::

 - (void)transitionFromViewController:(UIViewController *)fromViewController 
  toViewController:(UIViewController *)toViewController  duration:(NSTimeInterval)duration  
  options:(UIViewAnimationOptions)options  animations:(void (^)(void))animations  
  completion:(void (^)(BOOL finished))completion
交换两个子视图控制器的位置(由于添加的顺序不同,所以子试图控制器在父视图控制器中存在层次关系)
fromViewController:当前显示的子试图控制器,将被替换为非显示状态
toViewController:将要显示的子视图控制器
duration:交换动画持续的时间,单位秒
options:动画的方式
animations:动画Block
completion:完成后执行的Block

4. - (void)willMoveToParentViewController:(UIViewController *)parent

当一个视图控制器从视图控制器容器中被添加或者被删除之前,该方法被调用
parent:父视图控制器,如果没有父视图控制器,将为nil

1. 当我们向我们的视图控制器容器中调用removeFromParentViewController方法时,必须要先调用该方法,且parent参数为nil:
[将要删除的视图控制器 willMoveToParentViewController:nil];
2. 当我们调用addChildViewController方法时,不需要显示调用。

5. - (void)didMoveToParentViewController:(UIViewController *)parent

当从一个视图控制容器中添加或者移除viewController后,该方法被调用。
parent:父视图控制器,如果没有父视图控制器,将为nil

1. 当我们向我们的视图控制器容器中调用addChildViewController方法时,必须要先调用该方法,且parent参数为 self:
2. 当我们调用removeFromParentViewController方法时,不需要显示调用该方法。

注: 需要在transitionFromViewController方法之前调用:[子视图控制器 willMoveToParentViewController:nil];
之后,调用[子视图控制器didMoveToParentViewController:父视图控制器];