present/push的恩怨情仇

本文深入探讨了iOS中`pushViewController`与`popViewController`的使用,分析了`UINavigationController`的VC栈存储机制,讨论了`present`和`dismiss`的交互方式。在`UINavigationController`中,`popToRootViewController`能够返回根视图,而`dismiss`可以用于关闭模态视图。文章还提到了在多级`present`的场景下如何返回根视图,并解决了一些返回过程中的小问题。
摘要由CSDN通过智能技术生成

push/pop

简介

pushViewController 导航控制器入栈的方式切换页面

popViewController
导航控制器出栈的方式返回上一页面

VC栈存储

container view controller

container view controller 指的是VC的容器类,通过container view controller,我们可以很方便的管理子VC,实现VC之间的跳转等,iOS中container view controller包括 UINavigationController, UISplitViewController, 以及 UIPageViewController.

push/pop是将旧视图存储在了VC栈中,因此我们可以这样操作:

假如

从A—(push)—>B—(push)—>C—(push)—>D—(popToRootViewController)—>A

如果在D视图进行操作:

NSLog(@"%@",self.navigationController.viewControllers);

则会打印:

2019-09-28 19:42:50.576198+0800 1111[995:32530] (
    "<AViewController: 0x7fdc41d00480>",
    "<BViewController: 0x7fdc3ec0a010>",
    "<CViewController: 0x7fdc3ef1b1e0>",
    "<DViewController: 0x7fdc3ef1b530>"
)

这就是push的VC栈的内容。
因此,我们可以进行这样的pop跳转:

    [self.navigationController popToViewController:self.navigationController.viewControllers[0] animated:YES];

这是因为我们可以看到,viewControllersNSArray类型的,所以可以通过下标跳转到指定界面。

优势

VC栈存储的优势在于:

  1. 可以直接跳转到根视图:

    • 通过popToRootViewController方法,把栈清空,直接回到根视图。
  2. 可以跳转到指定界面:

    • 通过popToViewController:方法 和 NSArray类型的viewControllers,可以跳转到指定的视图。

dealloc

那么,在我们通过popToRootViewController方法回到根视图的时候,A视图后面的B、C、D视图会怎样呢?

答案是:按数组顺序依次销毁。
可以通过在B、C、D视图添加:

- (void)dealloc {
    NSLog(@"当前视图名称 dealloc");
}

可以发现,最后会这样打印:

2019-09-28 20:00:39.291619+0800 1111[1108:40814] AViewController viewWillAppear
2019-09-28 20:00:39.296359+0800 1111[1108:40814] BViewController dealloc
2019-09-28 20:00:39.296798+0800 1111[1108:40814] CViewController dealloc
2019-09-28 20:00:39.802419+0800 1111[1108:40814] DViewController dealloc

会先出现A视图,然后按数组顺序依次dealloc。

也就是说,它是按栈存储的,但是并不符合后进先出的原理。(???)

可能是把栈里的视图先取出,放到里另一个栈sNew里,当top指的是根视图时,先把根视图显示,再把栈sNew里的视图依次移除

navigationController

讨论push/pop,就不得不讨论navigationController

无navigationController的界面push

当我们从一个有navigationController的A界面用present跳转到B界面后,B界面将没有navigationController,若还在B界面用push方法,即如下:

    CViewController *cViewController = [[CViewController alloc]init];
    NSLog(@"跳转到C界面");
    [self.navigationController pushViewController:cViewController animated:YES];

则界面不会跳转,会一直停留在B界面&#

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值