博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
使用addChildViewController手动控制UIViewController的切换
阅读量:6198 次
发布时间:2019-06-21

本文共 6866 字,大约阅读时间需要 22 分钟。

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 
@interface AppDelegate : UIResponder
@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 
@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 
@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 
@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的功能.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

转载地址:http://tbjca.baihongyu.com/

你可能感兴趣的文章
独家!阿里开源自用OpenJDK版本,Java社区迎来中国力量
查看>>
Courier:Dropbox 基于gRPC 的 RPC 框架开发过程
查看>>
腾讯云一站式物联PaaS平台IOT Suite助力行业加速“物联网+”
查看>>
Kafka 2.0重磅发布,新特性独家解读
查看>>
破译密码、设计飞机和建设团队:Randy Shoup谈高绩效团队
查看>>
饿了么研发总监马尧:外卖推荐算法中有哪些机制与手段?
查看>>
如何在 Kubernetes 中对无状态应用进行分批发布
查看>>
Java程序员:不要因未知而让云成本大涨
查看>>
Git漏洞导致攻击者可在用户电脑上运行任意代码
查看>>
F# 2017回顾
查看>>
业务中台探索和实践:软件的根本问题
查看>>
云平台宕机引发的系列思考,企业如何自救?
查看>>
LFE将Lisp编程带到Erlang虚拟机上
查看>>
QCon北京2015:移动开发最佳实践专题前瞻
查看>>
Trello中的Scrum
查看>>
Thanos如何让Prometheus更易用?
查看>>
Kubernetes上的十大应用程序
查看>>
Gartner有关Java EE正在消亡的报告是否太言过其实了?
查看>>
使用Mono将C#编译运行至WebAssembly平台
查看>>
一文带你快速读懂.NET CLI
查看>>