详解iOS的presentViewController

详解iOS的presentViewController这些场景都会暂时中断APP的正常执行流程,主要作用是收集信息以及显示一些重要的提示等。 container view controller 指的是VC的容器类,通过container view controller,我们可以很方便的管理子VC,实现VC之间的跳转等,iOS中co…

用途和相关概念

iOS中显示ViewController的方式有两种push和modal,modal也叫模态,模态显示VC是iOS的重要特性之一,其主要用于有以下场景

  • 收集用户输入信息
  • 临时呈现一些内容
  • 临时改变工作模式
  • 相应设备方向变化(用于针对不同方向分别是想两个ViewController的情况)
  • 显示一个新的view层级

这些场景都会暂时中断APP的正常执行流程,主要作用是收集信息以及显示一些重要的提示等。

presenting view controller & presented view controller

当vcA模态的弹出了vcB,那么vcA就是presenting view controller,vcB就是presented view controller,具体在代码中体现如下:

vcA.present(vcB, animated: true, completion: nil)

container view controller

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

ModalPresentationStyle & Presentation Context

ModalPresentationStyle

presented VC 的modalPresentationStyle属性决定了此次presentation的行为方式及UIKit寻找presentation context的方法,iOS提供了以下几种常用的presentation style:

UIModalPresentationFullScreen

UIKit默认的presentation style。 使用这种模式时,presented VC的宽高与屏幕相同,并且UIKit会直接使用rootViewController做为presentation context,在此次presentation完成之后,UIKit会将presentation context及其子VC都移出UI栈,这时候观察VC的层级关系,会发现UIWindow下只有presented VC.

UIModalPresentationPageSheet

在常规型设备(大屏手机,例如plus系列以及iPad系列)的水平方向,presented VC的高为当前屏幕的高度,宽为该设备竖直方向屏幕的宽度,其余部分用透明背景做填充。对于紧凑型设备(小屏手机)的水平方向及所有设备的竖直方向,其显示效果与UIModalPresentationFullScreen相同。

UIModalPresentationFormSheet

在常规型设备的水平方向,presented VC的宽高均小于屏幕尺寸,其余部分用透明背景填充。对于紧凑型设备的水平方向及所有设备的竖直方向,其显示效果与UIModalPresentationFullScreen相同

UIModalPresentationCurrentContext

使用这种方式present VC时,presented VC的宽高取决于presentation context的宽高,并且UIKit会寻找属性definesPresentationContext为YES的VC作为presentation context,具体的寻找方式会在下文中给出 。当此次presentation完成之后,presentation context及其子VC都将被暂时移出当前的UI栈。

UIModalPresentationCustom

自定义模式,需要实现UIViewControllerTransitioningDelegate的相关方法,并将presented VC的transitioningDelegate 设置为实现了UIViewControllerTransitioningDelegate协议的对象。

UIModalPresentationOverFullScreen

与UIModalPresentationFullScreen的唯一区别在于,UIWindow下除了presented VC,还有其他正常的VC层级关系。也就是说该模式下,UIKit以rootViewController为presentation context,但presentation完成之后不会讲rootViewController移出当前的UI栈。

UIModalPresentationOverCurrentContext

寻找presentation context的方式与UIModalPresentationCurrentContext相同,所不同的是presentation完成之后,不会将context及其子VC移出当前UI栈。但是,这种方式只适用于transition style为UIModalTransitionStyleCoverVertical的情况(UIKit默认就是这种transition style)。其他transition style下使用这种方式将会触发异常。

UIModalPresentationBlurOverFullScreen

presentation完成之后,如果presented VC的背景有透明部分,会看到presented VC下面的VC会变得模糊,其他与UIModalPresentationOverFullScreen模式没有区别。

present VC是通过UIViewController的presentViewController: animated:completion: 函数实现的,在探讨他们之间的层级关系之前,我们首先要理解一个概念,就是presentation context。

presentation context是指为本次present提供上下文环境的类,需要指出的是,presenting VC通常并不是presentation context,Apple官方文档对于presentation context的选择是这样介绍的:

When you present a view controller, UIKit looks for a view controller that provides a suitable context for the presentation. In many cases, UIKit chooses the nearest container view controller but it might also choose the window’s root view controller. In some cases, you can also tell UIKit which view controller defines the presentation context and should handle the presentation.

从上面的介绍可以看出,当我们需要present VC的时候,除非我们指定了context,否则UIKit会优先选择presenting VC所属的容器类做为presentation context,如果没有容器类,那么会选择rootViewController。但是,UIKit搜索context的方式还与presented VC的modalPresentationStyle属性有关,当modalPresentationStyle为UIModalPresentationFullScreen、UIModalPresentationOverFullScreen等模式时,UIKit会直接选择rootViewController做为context。当modalPresentationStyle为UIModalPresentationOverCurrentContext、UIModalPresentationCurrentContext模式时,UIKit搜索context的方式如下:

UIModalPresentationOverCurrentContext、UIModalPresentationCurrentContext模式下,一个VC能否成为presentation context 是由VC的definesPresentationContext属性决定的,这是一个BOOL值,默认UIViewController的definesPresentationContext属性值是NO,而 container view controller的definesPresentationContext默认值是YES,这也是上文中,UIKit总是将container view controller做为presentation context的原因。如果我们想指定presenting VC做为context,只需要在presenting VC的viewDidLoad方法里添加如下代码即可:

self.definesPresentationContext = YES

UIKit搜索presentation context的顺序为:

  1. presenting VC
  2. presenting VC 的父VC
  3. presenting VC 所属的container VC
  4. rootViewController

还有另外一种特殊情况,当我们在一个presented VC上再present一个VC时,UIKit会直接将这个presented VC做为presentation context。

presenting VC 与presented VC 之间的层级关系

在iOS 中,presented VC 总是与 presentation context 处于同一层级,而与presenting VC所在的层级无关,且同一个presentation context同时只能有一个presented VC。

下面我们通过代码来验证这个结论。首先新建一个APP,各VC之间的层级关系如下:

这里写图片描述

在SecondContentVC中present FirstPresentVC,代码如下:

FirstPresentVC *vc = [[FirstPresentVC alloc] init];
vc.modalPresentationStyle = UIModalPresentationOverCurrentContext;
[self presentViewController:vc animated:YES completion:nil];

为了更好的观察各VC的层级关系,我们将presented VC 的modalPresentationStyle属性设置为UIModalPresentationOverCurrentContext,然后我们再看各VC之间的层级关系:

这里写图片描述

可以看到FirstPresentVC 与 SecondContentVC的navigationViewController处在同一层级,说明这时的presentation context是navigationViewController。下面我们在FirstContentVC的viewDidLoad方法里添加如下代码:

self.definesPresentationContext = YES;

弹出FirstPresentVC后再看VC之间的层级关系:

这里写图片描述

可以看到,FirstPresentVC 与 FirstContentVC 处在同一层级,说明此时的presentation context为FirstContentVC.

下面我们将SecondContentVC的definesPresentationContext属性设为YES,然后观察弹出FirstPresentVC之后的层级关系:

这里写图片描述

ModalTransitionStyle

modalTransitionStyle可以设置presentation的转场动画,官方提供了几种不同的转场动画,默认是UIModalTransitionStyleCoverVertical。如果想要使用别的style,只需要设置presented VC的modalTransitionStyle属性即可。其余三种包括:

  • UIModalTransitionStyleFlipHorizontal
  • UIModalTransitionStyleCrossDissolve
  • UIModalTransitionStylePartialCurl

具体每种style的表现形式参考Demo.

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
转载请注明出处: https://daima100.com/37088.html

(0)

相关推荐

  • idea编辑器的永久激活方法有哪些_idea2021.1永久激活

    idea编辑器的永久激活方法有哪些_idea2021.1永久激活激活成功教程方法:下载激活成功教程补丁→修改配置文件→输入激活码→激活成功(1)下载激活成功教程补丁 把下载的激活成功教程补丁放在你的idea的安装目录下的bin的目录下面(如下图所示),本文示例为D:\ProgramFiles\JetBrains\IntelliJIDEA2018.1.5\bin激活成功教程补丁下载:IntelliJIDEA2018.1.5​​​​​​​(2)修改配置文件 打开并编辑ide…

    2023-03-23
    335
  • java调用webservice接口 三种方法_java中string

    java调用webservice接口 三种方法_java中stringWebService是一种跨编程语言、跨操作系统平台的远程调用技术,已存在很多年了,很多接口也都是通过WebService方式来发布的,下面这篇文章主要给大家介绍了关于java调用WebServic…

    2023-07-01
    147
  • 使用Seaborn进行Python数据可视化

    使用Seaborn进行Python数据可视化a href=”https://www.python100.com/a/sm.html”font color=”red”免责声明/font/a a href=”https://beian.miit.gov.cn/”苏ICP备2023018380号-1/a Copyright www.python100.com .Some Rights Reserved.

    2024-09-21
    11
  • 线上千万级大表排序优化

    线上千万级大表排序优化前言   大家好我是不一样的科技宅,每天进步一点点,体验不一样的生活,今天我们聊一聊Mysql大表查询优化,前段时间应急群有客服反馈,会员管理功能无法按到店时间、到店次数、消费金额 进行排序。经过排…

    2023-02-03
    151
  • Python数据可视化利器:Matplotlib库的用法

    Python数据可视化利器:Matplotlib库的用法数据可视化已经成为了现代数据科学家和工程师的重要工作之一。Matplotlib是一个优秀的数据可视化库,它支持众多的绘图类型,包括线图,散点图,柱状图,等高线图,和复杂的3D图形。Matplotlib库的设计目标是兼容MATLAB语法,这使得它成为科学计算中最受欢迎的绘图库之一。

    2024-04-12
    86
  • 😎P03 DB 数据库的约束条件、表关系、修改表语法以及复制表😎[通俗易懂]

    😎P03 DB 数据库的约束条件、表关系、修改表语法以及复制表😎[通俗易懂]内容概要 约束条件 表与表之间建立关系(约束) 修改表的完整语法 复制表 约束条件 default默认值 """ # 补充:在插入数据的时候可以指定字段 create t

    2023-03-14
    154
  • 一个半月减掉20斤_减肥药一个月瘦20斤正常吗

    一个半月减掉20斤_减肥药一个月瘦20斤正常吗最近在网络上,降糖药“司美格鲁肽”火了,成为备受瘦身人群追捧的“减肥神药”,还曾一度断货。市民吴女士由于日常工作繁重,饮食、作息不规律,体重最高

    2023-07-12
    131
  • java constructor_java select

    java constructor_java select前面两篇文章介绍了NIO中的Buffer和Channel,有了之前的基础,这篇文章来介绍一下另一个比较重要的概念Selector。我们知道系统线程的切换是消耗系统资源的,如果我们每一个连接都用一个线程来管理,资源的开销会非常大,这个时候就可以用Selector。通过Se…

    2023-08-03
    134

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注