模态

原文链接

iOS中显示ViewController的方式有两种push和modal,modal也叫模态,其主要用于有以下场景:

  • 收集用户输入信息
  • 临时呈现一些内容
  • 临时改变工作模式
  • 显示一个新的view层级

presenting view controller / presented view controller

当vcA模态的弹出了vcB,那么VCA就是presenting view controller,
VCB就是presented view controller

[vcA presentViewController:vcB animated:YES completion:nil];

container view controller

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

ModalPresentationStyle

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

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

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

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

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

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

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

UIModalTransitionStyle

  • UIModalTransitionStyleCoverVertical
  • UIModalTransitionStyleFlipHorizontal
  • UIModalTransitionStyleCrossDissolve

presentation context

presentation context是指为本次present提供上下文环境的类,
需要指出的是,presenting VC通常并不是presentation context,
当我们需要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的方式如下:
一个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

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

你可能感兴趣的:(模态)