iOS——present相关属性以及dismiss多级的方法

push和present

  1. 两者的区别
  • push:
    push由视图栈控制,每一个视图都入栈,调用之前的视图则需要出栈,可返回任意一层,一般用于同一业务不同界面之间的切换。
    push是由UINavigationController管理的视图控制器堆栈,在window下同时只能显示一个ViewController。
  • present:
    present弹出的视图是模态视图(我对模态视图的理解大概就是一个临时视图),只能逐级返回,一般用于不同业务界面的切换。
    present是由UIViewController管理的视图控制器堆栈,在window下可以以叠加的方式展示,当顶层的view透明时可以看到底层的view,但只有顶层的view可用户交互。

对push和present的其他补充在我以前的博客中写到过:UI学习之——iOS中界面的推出方法

presentingViewController和presentedViewController

presentedViewController和presentingViewController的区别:
presentedViewController和presentingViewController是UIViewController中的两个属性,例如,如果ViewControllerA调用present(_:animated:completion:)方法将ViewControllerB呈现出来,那么ViewControllerA就是presentingViewController,ViewControllerB就是presentedViewController。
这两个概念在使用Modal视图控制器时非常有用,因为它们允许您跟踪当前视图控制器的状态以及它所呈现的视图控制器。

  1. presentedViewController:由这个视图控制器或它最近的祖先呈现的视图控制器
  2. presentingViewController:呈现此视图控制器(或其最远祖先)的视图控制器

dismiss多级的方法:

这里我们使用几个案例来说明:
假设我们有6个视图控制器,颜色和层级关系分别是红->橙->黄->绿->蓝->紫。

dismiss到根视图控制器

按照之前所学的,如果我们直接用dismiss方法,视图会从当前层级跳转到上一层级,那么如果我现在想让它从当前视图控制器直接dismiss到根视图控制器,应该怎么做呢?
给出代码实现:

#import "FiveViewController.h"
#import "FourViewController.h"@interface FiveViewController ()@end@implementation FiveViewController- (void)viewDidLoad {[super viewDidLoad];self.view.backgroundColor = [UIColor purpleColor];UIButton *button = [UIButton buttonWithType:UIButtonTypeSystem];[button setTitle:@"切换" forState:UIControlStateNormal];button.frame = CGRectMake(100, 300, 200, 80);[button addTarget:self action:@selector(press) forControlEvents:UIControlEventTouchUpInside];[self.view addSubview:button];}
- (void)press {//使用多级dismiss从当前视图返回根视图//首先创建一个UIViewController的实例对象,用于作为我们的根视图控制器//presentingViewController属性是指当前视图的上一个视图控制器,我们将刚刚创建的根视图控制器赋为当前视图的上一个视图UIViewController *rootViewController = self.presentingViewController;//进入一个循环,一直将该根视图控制器对象赋为它的前一个视图控制器,直到它的前一个视图控制器为nil,则表示我们找到了根视图控制器while (rootViewController.presentingViewController) {rootViewController = rootViewController.presentingViewController;}//使用dismiss回到根视图控制器[rootViewController dismissViewControllerAnimated:YES completion:nil];
}
@end

在该代码中,FourViewController是FiveViewController的上一级视图控制器,我们在当前页面先设置一个按钮,并为按钮设置事件函数。该事件函数中我们调用当前视图的presentingViewController属性来获取其上一级视图控制器对象,然后一直循环,直到我们获取到根视图控制器。

在此处,我一开始不理解为什么使用根视图控制器直接dismiss可以回到根视图控制器。因为之前一直以来,我对dismiss的理解都是“销毁当前视图控制器并返回上一级视图控制器”,而这里的rootViewController并不是当前视图控制器,它也没有上一级视图控制器,为什么能这样实现呢?
直到我查到了dismiss的文档描述:
如果您连续显示多个视图控制器,从而构建一个显示的视图控制器堆栈,则在堆栈中较低的视图控制器上调用此方法会解除其直接子视图控制器和堆栈中该子级以上的所有视图控制器。当发生这种情况时,只有最上面的视图以动画的方式被取消;任何中间视图控制器都只是从堆栈中删除。最上面的视图将使用其模态转换样式来消除,这可能与堆栈中较低的其他视图控制器使用的样式不同。
原来是这样,因此,这里不光是根视图控制器,改为其他任何一个视图控制器都是同理

结果演示:
在这里插入图片描述

dismiss指定级数

这里演示dismiss两级:

#import "FourViewController.h"
#import "FiveViewController.h"@interface FourViewController ()@end@implementation FourViewController- (void)viewDidLoad {[super viewDidLoad];self.view.backgroundColor = [UIColor blueColor];UIButton *button = [UIButton buttonWithType:UIButtonTypeSystem];[button setTitle:@"切换" forState:UIControlStateNormal];button.frame = CGRectMake(100, 300, 200, 80);[button addTarget:self action:@selector(press) forControlEvents:UIControlEventTouchUpInside];[self.view addSubview:button];UIButton *dismissTwoButton = [UIButton buttonWithType:UIButtonTypeSystem];[dismissTwoButton setTitle:@"dismiss两级(到黄色视图)" forState:UIControlStateNormal];dismissTwoButton.frame = CGRectMake(100, 500, 200, 80);[dismissTwoButton addTarget:self action:@selector(pressDismissTwo) forControlEvents:UIControlEventTouchUpInside];[self.view addSubview:dismissTwoButton];}
- (void)press {FiveViewController *five = [[FiveViewController alloc] init];[self presentViewController:five animated:YES completion:nil];
}- (void) pressDismissTwo {[self.presentingViewController.presentingViewController dismissViewControllerAnimated:YES completion:nil];
}@end

演示结果:
在这里插入图片描述

dismiss到目标视图控制器

通过dismiss跳转到目标视图控制器,同样也是要一级一级的通过presentingViewController属性进行遍历,不过这里的循环跳出条件是对便利到的视图控制器的类进行判断
代码实现:

#import "ThreeViewController.h"
#import "FourViewController.h"
#import "OneViewController.h"@interface ThreeViewController ()@end@implementation ThreeViewController- (void)viewDidLoad {[super viewDidLoad];self.view.backgroundColor = [UIColor greenColor];UIButton *button = [UIButton buttonWithType:UIButtonTypeSystem];[button setTitle:@"切换" forState:UIControlStateNormal];button.frame = CGRectMake(100, 300, 200, 80);[button addTarget:self action:@selector(press) forControlEvents:UIControlEventTouchUpInside];[self.view addSubview:button];UIButton *dismissButton = [UIButton buttonWithType:UIButtonTypeSystem];[dismissButton setTitle:@"dismiss到目标控制器(橙色)" forState:UIControlStateNormal];dismissButton.frame = CGRectMake(100, 500, 200, 80);[dismissButton addTarget:self action:@selector(pressDismiss) forControlEvents:UIControlEventTouchUpInside];[self.view addSubview:dismissButton];
}
- (void)press {FourViewController *four = [[FourViewController alloc] init];[self presentViewController:four animated:YES completion:nil];
}- (void) pressDismiss {//接下来演示从当前视图控制器dismiss到目标视图控制器//同样的,我们首先先创建一个视图控制器的实例对象,然后将其赋值为当前视图的前一个视图控制器UIViewController *muBiaoViewController = self.presentingViewController;//然后一样的进入while循环,但是此处不同的是出循环的条件是当该对象的父类是目标视图控制器类while (![muBiaoViewController isKindOfClass:[OneViewController class]]) {muBiaoViewController = muBiaoViewController.presentingViewController;}[muBiaoViewController dismissViewControllerAnimated:YES completion:nil];
}@end

在该代码中,ThreeViewController是当前视图控制器(绿色),FourViewController是当前视图控制器的上一级视图控制器,OneViewController是我们要跳转的目标视图控制器(橙色)。
演示结果:
在这里插入图片描述

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

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

相关文章

vue项目打包优化

首先第一步通过浏览器看首次加载的问题大小,时间跨度等方面入手 1. Coverage观察 Coverage是chrome开发者工具的一个新功能,从字面意思上可以知道它是可以用来检测代码在网站运行时有哪些js和css是已经在运行,而哪些js和css是还没有用到的&a…

PID之Simulink仿真

昨天,在中南大学面试的老师,老师突然问到如何调PID,关于PID,我只知道一些基本概念,实际中并没有做过相关PID的项目,就连仿真也没搞过,所以今天就照着网上的教程做了PID的仿真,调PID的…

实现人工智能的去中心化,权力下放是最佳途径!

Web3和人工智能(AI)的交集,已成为加密社区中最热门的争论话题之一。毕竟,生成式AI正在彻底改变传统软件堆栈的所有领域,Web3也不例外。鉴于去中心化是Web3的核心价值主张,许多新兴的Web3生成AI项目和场景都…

KT142C语音芯片flash型用户如何更新固件的说明_V2

目录 一、简介 2.1 让芯片进入PC模式 2.2 双击提供的exe程序即可 一、简介 正常的情况下,用户肯定是不需要更新固件的,因为芯片出厂默认就烧录了对应的程序固件,但是有客户可能需要小修小改,或者订制一下某些功能&#xff0c…

全国职业技能大赛云计算--高职组赛题卷②(容器云)

全国职业技能大赛云计算--高职组赛题卷②(容器云) 第二场次题目:容器云平台部署与运维任务1 Docker CE及私有仓库安装任务(5分)任务2 基于容器的web应用系统部署任务(15分)任务3 基于容器的持续…

浅谈SpringMVC的请求流程

目录标题 浅谈SpringMVC的请求流程SpringMVC的介绍SpringMVC的逻辑概念运行图解知识总结 浅谈SpringMVC的请求流程 对于SpringMVC而言重点是了解它的底层运行逻辑,从而可以根据其逻辑来进行实际业务的操作或者是利用原理增强业务的功能性,最终达到项目预…

FPGA:卷积编码及维特比译码仿真

FPGA:卷积编码及维特比译码仿真 本篇记录一下在FPGA中完成卷积编码和维特比译码的过程,通过代码解释编码的过程和译码的过程,便于理解,同时也方便移植到其他工程中。 1. 准备工作 卷积编译码IP核—convolutionIP核和viterbiIP核…

以太网协议

以太网 以太网协议格式🎨目的地址,源地址mac地址格式 以太网协议格式🎨 目的地址,源地址 此处的地址,叫做mac地址(物理地址),长度是6个字节 mac地址的作用也是用来区分不同的主机 IP地址的长度是4字节 IP地址负责网络层(整体)转发,mac地址负责数据链路层…

CHATGPT中国免费网页版有哪些-CHATGPT中文版网页

CHATGPT中国免费网页版,一个强大的人工智能聊天机器人。如果你曾经感到困惑、寻求答案,或者需要一些灵感,那么CHATGPT国内网页版可能会成为你的好朋友。 CHATGPT国内免费网页版:你的多面“好朋友” 随着人工智能技术的不断发展&a…

消息队列 记录

https://www.bilibili.com/video/BV1ia411k7oo/?p3&vd_source088e0f60c1207e991fcf231a9f1a0274

关于Godot动态生成节点的细节

var dy_btn Button.new()add_child(dy_btn)print(get_child(0).name) 此时获取的名词会带有动态类型,如果这个时候想通过特定的节点名词来获取节点是不行的 此时需要补充类似 dy_btn.name "a" 的代码,然后就能按照节点名词获取节点了