[BS-20] 导航控制器和视图控制器在添加控制器的区别

Posted stevenwuzheng

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[BS-20] 导航控制器和视图控制器在添加控制器的区别相关的知识,希望对你有一定的参考价值。

导航控制器和视图控制器在添加控制器的区别

 

1.

因导航控制器拥有导航栈,有一个普通视图控制器都没有的数组viewControllers,加入该数组中的视图控制器默认以push的方式进入导航栈。导航控制器有个[UINavigationController alloc] initWithRootViewController:rootVC]; 的初始化方法,调用该方法相当于把rootVC加入数组viewControllers的第一个位置,作为栈底部的rootVC是不会被pop出去的,与导航控制器共生死。加入导航栈的VC,在被push到栈顶时,VC.view会被创建/装载,并显示在window上,并不是将栈顶的VC.view加到下一层VC.view上,此时下一层VC.view已经不在UI层级中了。

2.

所有的视图控制器都有一个[viewController addChildViewControllerl:vc]的方法,使用该方法加入的vc,会自动存储在viewController的childViewControllers数组中(类似UIView的subViews数组)。

注意:只能通过addChildViewController的方法给childViewControllers数组增加元素,不能直接对其进行赋值,因为childViewControllers数组对程序员来说是只读的。

另外:viewController.childViewControllers中的所有vc仅仅表示是viewController的子控制器。子控制器的view不会自动加载到viewController.view上去,需要手动将子控制器view加到父视图控制器view或者view的任意子view上,才能显示在屏幕上。

 3.

因导航控制器又属于视图控制器,所以导航控制器也可以通过[navC addChildViewController:vc]; 给自己的childViewControllers数组添加子视图控制器,但是此方法增加的VC会被自动加入导航栈数组viewControllers中去。在某VC出现在栈顶时,它的view会被自动装载。

所以对于导航控制器viewControllers和childViewControllers中的内容是一模一样的,不同的是childViewControllers是只读的,而viewControllers是NSArray不可变数组,可以给它赋初始值。

4.

注意区别:

self.childViewControllers,

self.presentedViewController,

self.presentingViewController,

self.presentingViewController.childViewControllers,

self.navigationController.viewControllers,

self.navigationController.childViewControllers,

self.navigationController.viewControllers[0].childViewControllers

 5.

初始化navigationController的三种方法:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    
    _window = [[UIWindow alloc]initWithFrame:[[UIScreen mainScreen]bounds]];
    _window.backgroundColor = [UIColor whiteColor];
    
    
    WZEssenceViewController *essenceVC = [WZEssenceViewController new];
    WZNewViewController *newVC = [WZNewViewController new];
    WZFriendViewController *friendVC = [WZFriendViewController new];
    WZMeViewController *meVC = [WZMeViewController new];
    
    //方法一
//    UINavigationController *nav = [[UINavigationController alloc]initWithRootViewController:essenceVC];
//    [essenceVC.navigationController pushViewController:newVC animated:YES];

    
    //方法二
    UINavigationController *nav = [[UINavigationController alloc]init];
    nav.viewControllers = @[essenceVC, newVC, friendVC, meVC]; //默认以push的方式进入导航站
    //nav.childViewControllers = @[essenceVC, newVC, friendVC, meVC]; //是只读的,不能赋值
    NSLog(@"nav.viewControllers:%@ \n nav.childViewControllers:%@ ",nav.viewControllers,nav.childViewControllers);

//    //方法三
//    UINavigationController *nav = [[UINavigationController alloc]init];
//    [nav addChildViewController:essenceVC];
//    [essenceVC.navigationController pushViewController:newVC animated:YES];
 
    
    _window.rootViewController = nav;
    
    [_window makeKeyAndVisible];
    
    
    return YES;
}


打印结果如下:
2016-05-16 19:11:24.784 
nav.viewControllers:(
    "<WZEssenceViewController: 0x7d178d00>",
    "<WZNewViewController: 0x7d179a20>",
    "<WZFriendViewController: 0x7d17a160>",
    "<WZMeViewController: 0x7d17a7f0>"
) 
 nav.childViewControllers:(
    "<WZEssenceViewController: 0x7d178d00>",
    "<WZNewViewController: 0x7d179a20>",
    "<WZFriendViewController: 0x7d17a160>",
    "<WZMeViewController: 0x7d17a7f0>"
) 

 

以上是关于[BS-20] 导航控制器和视图控制器在添加控制器的区别的主要内容,如果未能解决你的问题,请参考以下文章

JSQ 消息视图控制器:在导航栏上添加“返回”按钮和图像,Swift

在导航控制器中添加子视图覆盖导航栏

iPhone - 如何将导航控制器添加到视图?

使用 TableView 向视图控制器添加导航

在推入导航控制器的控制器中添加子视图控制器

在表格视图导航控制器之前添加快速视图控制器的推荐结构