使用addChildViewController手动控制UIViewController的切换

使用addChildViewController手动控制UIViewController的切换

addChildViewController


If the new child view controller is already the child of a container view controller, it is removed from that container before being added.
This method is only intended to be called by an implementation of a custom container view controller. If you override this method, you must call super in your implementation.

如果这个子 view controller 已经被添加到了一个容器 controller 当中,那在它被添加进新的容器controller之前会从旧的容器中移除.

这个方法只能被用来实现一个自定义的容器controller添加子controller.如果你重写了这个方法,你必须调用super方法.

 

使用源码:

使用addChildViewController手动控制UIViewController的切换

 

AppDelegate.h + AppDelegate.m

#import <UIKit/UIKit.h>



@interface AppDelegate : UIResponder <UIApplicationDelegate>



@property (strong, nonatomic) UIWindow *window;



@end
#import "AppDelegate.h"

#import "RootViewController.h"



@implementation AppDelegate



- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions

{

    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];



    // 加载根视图控制器

    self.window.rootViewController = [RootViewController new];

    

    self.window.backgroundColor = [UIColor whiteColor];

    [self.window makeKeyAndVisible];

    return YES;

}



@end

RootViewController.h + RootViewController.m

#import <UIKit/UIKit.h>



@interface RootViewController : UIViewController



@end
#import "RootViewController.h"

#import "FirstViewController.h"

#import "SecondViewController.h"



// 获取当前屏幕尺寸

#define SCR_HEIGHT  [UIScreen mainScreen].bounds.size.height



// 设置按钮高度

static CGFloat downLenth   = 40.f;



// 标示button的枚举值

typedef enum

{



    BUTTON_1 = 0x11,

    BUTTON_2,



} EFlags;



@interface RootViewController ()



{

    

    UIViewController *currentVC;

    

}



@property (nonatomic, strong) UIView               *showArea;  // 加载子controller的view

@property (nonatomic, strong) FirstViewController  *firstVC;   // 子controller

@property (nonatomic, strong) SecondViewController *secondVC;  // 子controller



@end



@implementation RootViewController



- (void)viewDidLoad

{

    [super viewDidLoad];



    // 初始化控制器

    [self controllersInit];

    

    // 初始化要展示的区域

    [self showAreaInit];

    

    // 初始化按钮

    [self buttonsInit];

}



#pragma mark - 初始化控制器

- (void)controllersInit

{

    // 初始化两个控制器并作为root控制器的subController

    _firstVC   = [FirstViewController new];

    [self addChildViewController:_firstVC];

    [_firstVC didMoveToParentViewController:self];

    

    _secondVC  = [SecondViewController new];

    [self addChildViewController:_secondVC];

    [_secondVC didMoveToParentViewController:self];

}



#pragma mark - 初始化要展示的区域

- (void)showAreaInit

{

    // 初始化要展示的区域

    self.showArea = [UIView new];

    self.showArea.frame = CGRectMake(0, 0, 320, SCR_HEIGHT - downLenth - 10);

    self.showArea.layer.masksToBounds = YES;

    [self.view addSubview:_showArea];

    

    // 将第一个控制器的view添加进来展示

    [self.showArea addSubview:_firstVC.view];

    

    currentVC = _firstVC;

}



#pragma mark - 初始化按钮以及按钮事件

- (void)buttonsInit

{

    UIButton *firstVCButton = [UIButton new];

    [self.view addSubview:firstVCButton];

    firstVCButton.backgroundColor = [UIColor redColor];

    firstVCButton.tag       = BUTTON_1;

    firstVCButton.frame     = CGRectMake(0, SCR_HEIGHT - downLenth, 320 / 2, downLenth);

    [firstVCButton addTarget:self

                      action:@selector(buttonsEvent:)

            forControlEvents:UIControlEventTouchUpInside];

    

    UIButton *secondVCButton = [UIButton new];

    [self.view addSubview:secondVCButton];

    secondVCButton.backgroundColor = [UIColor yellowColor];

    secondVCButton.tag       = BUTTON_2;

    secondVCButton.frame     = CGRectMake(320 / 2, SCR_HEIGHT - downLenth, 320 / 2, downLenth);

    [secondVCButton addTarget:self

                      action:@selector(buttonsEvent:)

            forControlEvents:UIControlEventTouchUpInside];

}



- (void)buttonsEvent:(UIButton *)button

{

    if (button.tag == BUTTON_1)

    {

        if (currentVC == _firstVC)

        {

            return;

        }

        

        [self transitionFromViewController:currentVC

                          toViewController:_firstVC

                                  duration:0

                                   options:UIViewAnimationOptionTransitionNone

                                animations:^{

                                    

                                }

                                completion:^(BOOL finished) {

                                    currentVC = _firstVC;

                                }];

    }

    

    if (button.tag == BUTTON_2)

    {

        if (currentVC == _secondVC)

        {

            return;

        }

        

        [self transitionFromViewController:currentVC

                          toViewController:_secondVC

                                  duration:0

                                   options:UIViewAnimationOptionTransitionNone

                                animations:^{

                                    

                                }

                                completion:^(BOOL finished) {

                                    currentVC = _secondVC;

                                }];

    }

}



@end

FirstViewController.h + FirstViewController.m

#import <UIKit/UIKit.h>



@interface FristViewController : UIViewController



@end
#import "FristViewController.h"



@interface FristViewController ()



@end



@implementation FristViewController



- (void)viewDidLoad

{

    [super viewDidLoad];



    NSLog(@"FirstViewController viewDidLoad");

}



- (void)viewWillAppear:(BOOL)animated

{

    NSLog(@"FirstViewController viewWillAppear");

}



- (void)viewDidAppear:(BOOL)animated

{

    NSLog(@"FirstViewController viewDidAppear");

}



- (void)viewWillDisappear:(BOOL)animated

{

    NSLog(@"FirstViewController viewWillDisappear");

}



- (void)viewDidDisappear:(BOOL)animated

{

    NSLog(@"FirstViewController viewDidDisappear");

}



@end

SecondViewController.h + SecondViewController.m

#import <UIKit/UIKit.h>



@interface SecondViewController : UIViewController



@end
#import "SecondViewController.h"



@interface SecondViewController ()



@end



@implementation SecondViewController



- (void)viewDidLoad

{

    [super viewDidLoad];

    

    NSLog(@"SecondViewController viewDidLoad");

}



- (void)viewWillAppear:(BOOL)animated

{

    NSLog(@"SecondViewController viewWillAppear");

}



- (void)viewDidAppear:(BOOL)animated

{

    NSLog(@"SecondViewController viewDidAppear");

}



- (void)viewWillDisappear:(BOOL)animated

{

    NSLog(@"SecondViewController viewWillDisappear");

}



- (void)viewDidDisappear:(BOOL)animated

{

    NSLog(@"SecondViewController viewDidDisappear");

}



@end

使用addChildViewController手动控制UIViewController的切换使用addChildViewController手动控制UIViewController的切换

 

需要注意的地方:

1. 容器controller最好定义一个专门用来展示子controller相关view的区域,如例子中的,其中,masksToBounds很重要,要不然,整个controller都会被展示出来的.


    self.showArea = [UIView new];
    self.showArea.frame = CGRectMake(0, 0, 320, SCR_HEIGHT - downLenth - 10);
    self.showArea.layer.masksToBounds = YES;
    [self.view addSubview:_showArea];
   
    [self.showArea addSubview:_firstVC.view];

 

2. 调用完addChildViewController之后还需要调用didMoveToParentViewController,官方文档里面有说明.

 

3. 为什么在点击一个按钮切换控制器的时候,showArea什么都不用设置,为何还能显示出变化呢?

    其实这一点我也没弄明白为何呢.

4. 这个与UITabbarController的功能类似,都有懒加载功能,实际上可以用来当做模拟UITabbarController使用,具备更高自由度的定制Tabbar的功能.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

你可能感兴趣的:(controller)