【iOS】present和push

【iOS】present和push

present和push的比较

  1. present和push都用于iOS的视图切换,并且切换都是可逆的,原始视图不会被销毁,还可以直接更改window的rootViewController来切换视图,但是这种方法不可逆,并且原始视图会被销毁

  2. present一般用于不同业务界面的切换,push一般用于同一业务不同界面的切换

  3. present和dismiss对应,push和pop对应

  4. present只能逐级返回,push有栈控制,但是可以返回任意级 ?

push方法

SecondViewController* secondViewController = [[SecondViewController alloc] init];
[self.navigationController pushViewController:secondViewController animated:YES];

pop方法

//返回上一级视图
[self.navigationController popViewControllerAnimated:YES];
//返回根视图
[self.navigationController popToRootViewControllerAnimated:YES];
//返回指定级数
[self.navigationController popToViewController:[self.navigationController.viewControllers objectAtIndex:0]];

这里返回到指定级数的方法,是通过访问视图控制器属性来获得视图控制器数组,在这个数组中可以获得导航控制器的每一层视图,再调用popToViewController方法就可以回到指定级数的视图。

present方法

SecondViewController* secondViewController = [[SecondViewController alloc] init];
[self presentViewController:secondViewController animated:YES completion:nil];

dismiss方法

[self dismissViewControllerAnimated:NO completion:nil];

dismiss多级的方法

两个属性

在讲解dismiss多级视图控制器的方法之前,先来了解一下presentedViewController和presentingViewController这两个UIViewController的属性。

presentedViewController:The view controller that was presented by this view controller or its nearest ancestor. 由这个视图控制器或它最近的祖先呈现的视图控制器 presentingViewController:The view controller that presented this view controller (or its farthest ancestor.) 呈现此视图控制器(或其最远祖先)的视图控制器。

举个例子:如果B控制器是由A控制器present弹出的,那么:

A.presentedViewController = B;

B.presentingViewController = A;

dismiss多级

现在来实现A、B、C、D四个视图控制器通过dismiss来实现多级之间的跳转。假设A、B、C、D四个视图之间的跳转关系为A->B->C->D

由D视图dismiss到A视图

UIViewController *rootViewController = self.presentingViewController;
while (rootViewController.presentingViewController) {rootViewController = rootViewController.presentingViewController;
}
[rootViewController dismissViewControllerAnimated:YES completion:nil];

dismiss两级

[self.presentingViewController.presentingViewController dismissViewControllerAnimated:YES];

也可以向前遍历来访问要dismiss的视图

UIViewController *ViewController = self.presentingViewController;
while (![ViewController isKindOfClass:[SecondViewController class]]) {ViewController = ViewController.presentingViewController;
}
[ViewController dismissViewControllerAnimated:YES completion:nil];

注意

这里的dismiss与我们以前常用的dismiss用法不同,以前都是被切换出的视图控制器调用dismiss方法来回到上一级视图控制器。而这里却是要回到哪一级视图控制器,就哪一级视图控制器调用dismiss方法。

那么dismissViewController到底在哪里执行呢?

其实,如果由A跳转到B,presentViewController方法在A里面执行,而dismissViewController也是A视图控制器来调用

苹果文档里的一段话: The presenting view controller is responsible for dismissing the view controller it presented. If you call this method on the presented view controller itself, it automatically forwards the message to the presenting view controller. 翻译如下: 呈现视图控制器负责解散它呈现的视图控制器。如果你在被呈现的视图控制器本身上调用这个方法,它会自动将消息转发给呈现的视图控制器。

什么意思呢?

其实就是如果在B中调用dismiss方法,dismiss方法会自动交给B的presentingViewController(也就是AViewController)来执行。

//在B中返回上一级
[self dismissViewControllerAnimated:NO completion:nil];
[self.presentingViewController dismissViewControllerAnimated:NO completion:nil];
//这两种写法效果一致

对于在A中执行dismiss从而实现多级跳转到A的解释如下:

苹果文档里的解释 If you present several view controllers in succession, thus building a stack of presented view controllers, calling this method on a view controller lower in the stack dismisses its immediate child view controller and all view controllers above that child on the stack. When this happens, only the top-most view is dismissed in an animated fashion; any intermediate view controllers are simply removed from the stack. The top-most view is dismissed using its modal transition style, which may differ from the styles used by other view controllers lower in the stack. 翻译如下: 如果你连续展示多个视图控制器,从而构建了一个由被展示的视图控制器组成的堆栈,那么在堆栈中较低位置的视图控制器上调用这个方法,会解除其直接子视图控制器以及该子视图控制器上方堆栈中的所有视图控制器。当这种情况发生时,只有最顶层的视图是以动画方式被解除展示的;任何中间的视图控制器都会直接从堆栈中移除。最顶层的视图使用其模态过渡样式来解除展示,该样式可能与堆栈中较低位置的其他视图控制器使用的样式不同。

也就是说,当present多个视图控制器时,系统维护了一个栈,栈中存放着A、B、C、D四个视图控制器。当在A中执行dismiss方法,栈中在A之上的视图就会被dismiss掉,不同的是,栈顶视图会以动画形式dismiss,而中间的视图控制器只是简单地remove掉。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/53964.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Python机器学习】循环神经网络(RNN)——超参数

几乎所有模型都可以根据数据和样本进行调整,它们都有各自的优势和相应的利弊权衡方式。寻找最优超参数集通常是一个棘手的问题,但是人类的直觉和经验可以为我们提供解决问题的方法。比如之前的例子: #设置任意输入序列的最大长度 maxlen100 …

鸿蒙 ArkUI组件二

ArkUI组件(续) 文本组件 在HarmonyOS中,Text/Span组件是文本控件中的一个关键部分。Text控件可以用来显示文本内容,而Span只能作为Text组件的子组件显示文本内容。 Text/Span组件的用法非常简单和直观。我们可以通过Text组件来显…

Doris相关记录

Doris工作整理 Doris索引、分区及物化视图踩坑 Doris向量化引擎理解与Clickhouse对比 Flink写Doris的checkpoint及label问题 Doris新增节点分片数据自动迁移

多模态大语言模型综述(中)-算法实用指南

本文是Multimodal Large Language Models: A Survey的译文之算法实用指南部分。 上:摘要、概念与技术要点实用指南中:算法实用指南(本文)下: 任务的实用指南(应用)、挑战等 原始信息 标题: Multimodal Large Language Models: A Survey译文: 多模态大…

拓扑排序算法

拓扑排序算法 上图意思为在我想要完成C7这件事之前我必须先完成事件C1,在完成C5这件事之前我必须先完成事件C6和C3.由图可以提看出拓扑序列是不唯一的。 有向图拓扑排序算法基本步骤: 1.从图中选择一一个入入度为0的顶点, 输出该顶点; 2.从图中删除该…

算子加速(3):自定义cuda扩展

文章目录 1.CUDA 扩展介绍1.1 CUDA 检查1.2 项目结构2 简单案例2.1 c++ 代码2.2 cu 核函数2.3 setup.py文件2.4 python文件3 进阶案例3.1 c++ 代码实现3.2 cuda 核函数的实现3.2.1 forward 方法3.2.2 backward 方法3.3 setup.py3.4 python 调用4.完整代码需要自定义某个层,或有…

MutationObserver详解+案例——深入理解 JavaScript 中的 MutationObserver:原理与实战案例

目录 深入理解 JavaScript 中的 MutationObserver:原理与实战案例 一、MutationObserver 简介 二、MutationObserver 的工作原理 1、基本用法 2、observe 方法的配置项 三、实战案例 案例 1:监控动态内容加载 案例 2:监控属性变化 案…

springboot 项目获取 yaml/yml (或 properties)配置文件信息

文章目录 springboot 项目获取配置文件信息前言1、 Autowired 注入 Environment类2、基础用法,使用Value注解直接注入配置信息3、进阶方法(推荐使用)拓展:springboot 集成配置中心 - 以 Apollo 为例 springboot 项目获取配置文件信…

通信工程学习:什么是接入网(AN)中的TF传送功能

接入网(AN)中的TF传送功能 在通信工程中,TF(Transfer Function)传送功能是指为接入网(AN)不同位置之间提供通道和传输介质,以实现数据的有效传输。以下是关于TF传送功能的详细解释&a…

PMP--一模--解题--91-100

文章目录 13.干系人管理91、 [单选] 在项目执行期间,一名外部干系人反对一项重大范围变更。除非重新评估干系人的决定,否则项目进展将受到影响。项目经理下一步该怎么做? 5.范围管理92、 [单选] 一客户给你一复杂项目的采购工作说明书&#x…

配置全新服务器深度学习一套流程

目录 1.安装anaconda2.配置cuda3.配置cudnn4.配置新的pytorch环境5.安装rdkit包6.小问题记录 1.安装anaconda 直接参考视频 总结: 1.下载anaconda安装包,尽量不下载最新的版本 2.bash 对应安装包,一直回车,yes 3.配置环境vim ~/.…

CSS3中的@media查询

CSS3的media查询是一种强大的功能,允许我们根据不同的媒体类型和设备特性来应用不同的样式规则。这使得我们能够创建响应式设计,确保网站或应用在各种设备和屏幕尺寸上都能提供良好的用户体验。本文将详细探讨media查询的定义、语法、使用场景及常见问题…

C++学习笔记(26)

七 、显示字符串中的字符 从界面上输入一个字符串(C 风格),把字符串中的每个字符显示出来,如果输入的是"abc",要求: 1)正序显示:a b c 2)逆序显示:…

实战千问2大模型第三天——Qwen2-VL-7B(多模态)视频检测和批处理代码测试

画面描述:这个视频中,一位穿着蓝色西装的女性站在室内,背景中可以看到一些装饰品和植物。她双手交叉放在身前,面带微笑,似乎在进行一场演讲或主持活动。她的服装整洁,显得非常专业和自信。 一、简介 阿里通义千问开源新一代视觉语言模型Qwen2-VL。其中,Qwen2-VL-72B在大…

vue2——使用Element-UI实现可搜索的树形结构

树形结构在日常开发中非常常见,例如菜单、组织架构等场景。Element-UI作为一款基于Vue.js的桌面端组件库,提供了丰富的组件供开发者使用。其中,Tree组件可以轻松实现树形结构的展示。但在实际项目中,我们往往需要实现可搜索的树形…

在k8s中,客户端访问服务的链路流程,ingress--->service--->deployment--->pod--->container

ingress是一个API资源。 其核心作用是nginx网页服务器。 当客户端访问服务器不同的url时, 用不同的location提供服务。 在k8s之外,nginx的配置一般如下: http {server {listen 80;server_name localhost;location / {root html; …

【鸿蒙OH-v5.0源码分析之 Linux Kernel 部分】003 - vmlinux.lds 链接脚本文件源码分析

【鸿蒙OH-v5.0源码分析之 Linux Kernel 部分】003 - vmlinux.lds 链接脚本文件源码分析 系列文章汇总:《鸿蒙OH-v5.0源码分析之 Uboot+Kernel 部分】000 - 文章链接汇总》 本文链接:《【鸿蒙OH-v5.0源码分析之 Linux Kernel 部分】003 - vmlinux.lds 链接脚本文件源码分析》 …

鸿蒙开发入门day19-使用NDK接口构建UI(一)

(创作不易,感谢有你,你的支持,就是我前行的最大动力,如果看完对你有帮助,还请三连支持一波哇ヾ(@^∇^@)ノ) 目录 NDK接口概述 整体架构 开发流程 接入ArkTS页面 占位组件 NDK组…

unity3d入门教程六

unity3d入门教程六 15.1预制体15.2编辑预制体15.3在场景中编辑15.4动态创建实例15.5实例的销毁16.1(练习)子弹发射16.2定时器16.3键盘事件 15.1预制体 火神山10天建成,使用了预制体技术 一个个小房间都是事先建造好的,最后吊车装…

观众登记2025中国(深圳)国际智能手机供应链展览会

时间:2024年4月9-11日 地点:深圳会展中心 ◆展会背景background: 近年来,国内手机品牌在全球市场上的影响力不断增强,华为、OPPO、VIVO和小米等…