zoukankan      html  css  js  c++  java
  • 使用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方法.

    使用源码:

    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

    需要注意的地方:

    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的功能.

  • 相关阅读:
    第11组 Beta冲刺(1/5)
    第11组 Alpha事后诸葛亮
    第11组 Alpha冲刺(6/6)
    第11组 Alpha冲刺(5/6)
    软工实践个人总结
    第11组 Beta版本演示
    第11组 Beta冲刺(5/5)
    第11组 Beta冲刺(4/5)
    第11组 Beta冲刺(3/5)
    第11组 Beta冲刺(2/5)
  • 原文地址:https://www.cnblogs.com/YouXianMing/p/3666691.html
Copyright © 2011-2022 走看看