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

news2024/11/16 7:30:33

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.coloradmin.cn/o/1033290.html

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

相关文章

CSS3实现上下拉长加载动画效果

上下拉长加载动画效果 <!DOCTYPE html> <html><head><style>.container {display: flex;justify-content: center;align-items: center;width: 150px;height: 150px;margin: 50px auto;}.rectangle {width: 20px;height: 50px;background-color: #02A…

黑马JVM总结(十九)

&#xff08;1&#xff09;GC调优1 通过官网查看查看JVM的参数&#xff1a; 可以使用java命令查看当前环境下的虚拟机参数&#xff1a; 学会使用一些工具如前面学的jmap &#xff0c;jconsole等等工具 &#xff08;2&#xff09;GC调优2 垃圾回收调优只是众多调优中的一个方…

基于微信小程序的电动车智能充电系统设计与实现(源码+lw+部署文档+讲解等)

文章目录 前言运行环境说明用户的主要功能有&#xff1a;管理员的主要功能有&#xff1a;具体实现截图详细视频演示为什么选择我自己的网站自己的小程序&#xff08;小蔡coding&#xff09;有保障的售后福利 代码参考论文参考源码获取 前言 &#x1f497;博主介绍&#xff1a;✌…

THREE.JS 3D模型服务器报404问题(VUE fbx文件在本地能显示 服务器上不显示报404)

问题&#xff1a; 作为新手&#xff0c;新建立的threeJS模型&#xff0c;本地运行模型是可以显示的 &#xff0c;但服务器模型却报404 写法&#xff1a; fbxloader("TR7007Q").then((tree) > { tree.position.set(-1080, -20, 0);this.$refs.draw.scene.add(tree…

编辑.htaccess文件执行任意代码(CVE-2022-25578)

简介 CVE-2022-25578是Taocms v3.0.2中存在的一个安全漏洞&#xff0c;该漏洞允许攻击者通过任意编辑.htaccess文件来执行代码注入攻击。 Taocms是一个完善支持多数据库&#xff08;Sqlite/Mysql&#xff09;的CMS网站内容管理系统&#xff0c;是国内最小且功能完善的基于php…

DM/达梦数据库查询或更新某一列中多个字典码对应内容

准备工作&#xff08;建表、插入数据&#xff09; 1、建立表格&#xff1a;学生-学习科目表student_study 注意&#xff1a;科目kemu列内容是字典码&#xff0c;需要更换成对应内容。 CREATE TABLE "TEST"."STUDENT_STUDY" ( "NAME" VARCHAR(2…

技术分享| anyRTC音视频混流技术解析

一&#xff0c;简介 在视频通讯场景中&#xff0c;比如会议、直播等经常能看到图像合成的场景。图像合成是在指定的一块画面区域&#xff0c;在这个区域内&#xff0c;按画面的位置(坐标)布局&#xff0c;将区域中的每个视频画面的像素混合计算成一个像素&#xff08;RGB&…

深度学习中的激活函数 – 完整概述

1.什么是激活函数? 生物神经网络启发了人工神经网络的发展。然而,人工神经网络甚至不能近似代表大脑的工作方式。在我们知道为什么在人工神经网络中使用激活函数之前,了解生物神经网络中激活函数的相关性仍然很有用。 典型的神经元具有由细胞体、向其他神经元发送信息的轴…

源码:TMS FlexCel Studio for .NET 7.19

TMS FlexCel Studio for .NET 是100% 托管代码 Excel 文件操作引擎以及 Excel 和 PDF 报告生成&#xff0c;适用于 .NET、Xamarin.iOS、Xamarin.Android、Xamarin.Mac、Windows Phone 和 Windows Store 功能概述 使用 FlexCel Studio for .NET 创建可动态快速读写 Excel 文件的…

SQLite 3.43 发布,性能大提升!

前言 SQLite是一种被广泛运用的嵌入式关系型数据库管理系统&#xff0c;最新发布的SQLite 3.43版本带来了一个重要的改进&#xff0c;大幅提升了对JSON数据的处理性能&#xff0c;达到了之前的两倍。 主要更新 添加对 Contentless-Delete FTS5 索引的支持。这是 FTS5 全文搜索…

Go 常用命令介绍

Go 常用命令 文章目录 Go 常用命令一、Go 常用命令1.1 go build1.1.1 指定输出目录1.1.2 常用环境变量设置编译操作系统和 CPU 架构1.1.3 查看支持的操作系统和CPU架构 1.2 go test1.3 go vet1.4 go clean1.5 go fmt1.6 go get1.7 go install1.8 go tool1.9 go generate1.10 go…

iOS——KVC(键值编码)

键值编码&#xff08;KVC&#xff09; KVC&#xff08;Key Value Coding&#xff09;是一种允许以字符串形式间接操作对象属性的方式。 最基本的KVC是由NSKeyValueCoding协议提供支持&#xff0c;最基本的操作属性如下&#xff1a; setValue: 属性值 forKey: 属性名&#xff…

Flink1.14 Source概念入门讲解与源码解析

目录 Flink Source概念 Source Source源码 getBoundedness() createReader(SourceReaderContext readerContext) createEnumerator(SplitEnumeratorContext enumContext) SplitEnumerator restoreEnumerator(SplitEnumeratorContext enumContext, EnumChkT checkpoint) …

使用Selenium进行网页登录和会话管理

随着互联网的快速发展&#xff0c;网页登录和会话管理是许多网站和应用程序的基本功能。通过网页登录&#xff0c;用户可以访问个人账户、购物车订单、历史记录等个性化信息。为了提高用户体验和效率&#xff0c;自动化登录和会话管理成为一个重要的需求。而Selenium作为一种强…

信创办公–基于WPS的EXCEL最佳实践系列 (限制可录入内容)

信创办公–基于WPS的EXCEL最佳实践系列 &#xff08;限制可录入内容&#xff09; 目录 应用背景操作过程1、数据有效性&#xff08;支出证明单&#xff09;2、如何完成数据有效性的使用&#xff08;差旅报销申请表&#xff09;3、清除数据验证4、利用圈释无效数据&#xff0c;验…

Docker容器中的SSH免密登录

简介&#xff1a;在日常的开发和测试环境中经常需要创建和管理Docker容器。有时&#xff0c;出于调试或管理的目的&#xff0c;可能需要SSH到容器内部。本文将介绍如何创建一个Docker容器&#xff0c;它在启动时自动运行SSH服务&#xff0c;并支持免密登录。 历史攻略&#xf…

在github上设置不同分支,方便回滚

在github上设置不同分支&#xff0c;方便回滚 步骤可能出现的问题couldnt find remote ref gpuVersion1. 确保您处于正确的分支2. 添加并提交更改&#xff08;如果还未进行&#xff09;3. 推送本地分支到远程仓库4. 验证操作 步骤 之前在github上上传了一个项目代码&#xff0c…

用Win10自带画图3D抠图

文章目录 一、打开“画图3D”二、插入图片三、抠图操作四、保存抠图 一、打开“画图3D” 在搜索框输入“画图3D” 选择彩色水滴图标的软件 二、插入图片 选择“新建” 导航栏“菜单”–>“插入”&#xff0c;选择要扣的图片。&#xff08;我选择了一张自己随意画的图片…

【动态规划刷题 17】回文子串 最长回文子串

647. 回文子串 链接: 647. 回文子串 给你一个字符串 s &#xff0c;请你统计并返回这个字符串中 回文子串 的数目。 回文字符串 是正着读和倒过来读一样的字符串。 子字符串 是字符串中的由连续字符组成的一个序列。 具有不同开始位置或结束位置的子串&#xff0c;即使是由…

启动 React APP 后经历了哪些过程

本文作者为 360 奇舞团前端开发工程师 前言 本文中使用的React版本为18&#xff0c;在摘取代码的过程中删减了部分代码&#xff0c;具体以源代码为准。 在React 18里&#xff0c;通过ReactDOM.createRoot创建根节点。并且通过调用原型链上的render来渲染。 本文主要是从以下两个…