UIModalPresentationStyle 各类类型的区别

UIViewController有个属性modalPresentationStyle,它决定了当前控制器 present 出的下一控制器的展现方式。html

官方文档对这些效果有比较详细的介绍,这里写个 demo 帮助理解,demo 在模拟器上运行可能会有一点卡顿,真机没有影响。git

预备知识

presenting、presented viewController

presentingViewController指的是 present 出当前控制器的控制器。github

presentedViewController指被当前控制器 present 出的控制器。swift

Size Class

对于各类常见状况的 Size Class 以下几张图片所示:app

iPhonePlus的SizeClass
iPhonePlus的SizeClass

普通iPhone的SizeClass
普通iPhone的SizeClass

全屏iPad的SizeClass
全屏iPad的SizeClass

UIModalPresentationStyle

enum UIModalPresentationStyle : Int {
    case fullScreen
    case pageSheet
    case formSheet
    case currentContext
    case custom
    case overFullScreen
    case overCurrentContext
    case popover
    case none
}
复制代码

fullScreen

  • 在各类 Size Class 状况下都是全屏展现
  • 执行 present 操做的控制器的view和它的subViews,在 present 完成后都会被从当前视图层级移除

fullScreen
fullScreen

对于水平方向为 compact 的状况,无论用哪一种 style 推出其余控制器,presentedViewController都是以fullScreen方式展现。因此剩下的全部类型,都只针对水平方向为 regular 论述。this

pageSheet

  • 被推出视图部分的遮盖下层视图
  • 其宽度老是为该设备竖屏时候的宽度(不可变),高度则为当前设备方向的屏幕高度(可变,其实还要去掉状态栏的高度)

pageSheet竖屏
pageSheet竖屏

pageSheet横屏
pageSheet横屏

formSheet

  • 被推出视图大小比屏幕的小,且老是居中显示
  • 在横屏时,若是弹出了键盘,视图位置会跟着上移
  • 能够设置被推出视图的preferredContentSize来设置它的大小

formSheet竖屏
formSheet竖屏

formSheet横屏
formSheet横屏

这里设置了preferredContentSize = CGSize(width: 200, height: 200)url

currentContext

  • 能够用在 iPadUISplitViewController中,指定单独覆盖屏幕单侧的控制器;popover方式展现的控制器,再用该方式 present 出下一视图
  • 在执行 present 操做的控制器的控制器层级中往上查找,若是某个控制器的definesPresentationContext == true则它来 present,假如没有一个为true,那么则由 window.rootController来 present
  • 执行 present 操做的控制器的view和它的subViews,在 present 完成后都会被从当前视图层级移除

definesPresentationContext默认为false,系统提供的一些像UINavigationController的控制器,其默认值为true。它的定义为:spa

A Boolean value that indicates whether this view controller's view is covered when the view controller or one of its descendants presents a view controller.3d

对于以currentContext方式推出的视图,若是它的presentedViewController是一个popover,那么推出该视图的modalTransitionStyle不能是partialCurl,不然会引发崩溃。代理

currentContext竖屏
currentContext竖屏

currentContext横屏
currentContext横屏

currentContextInPopover
currentContextInPopover

custom

A custom view presentation style that is managed by a custom presentation controller and one or more custom animator objects.

详细介绍在下篇文章中进行。

overFullScreen

基本和fullScreen一致。只是 present 完成后,不会移除执行 present 操做的控制器的view和它的subViews。若是presentedViewController.view是有透明度的,底层视图就能够得以显示。

overFullScreen
overFullScreen

overCurrentContext

基本和currentContext一致。只是 present 完成后,不会移除执行 present 操做的控制器的view和它的subViews。若是presentedViewController.view是有透明度的,底层视图就能够得以显示。

overCurrentContext
overCurrentContext

popover

  • 在 iPad 上用popover的方式显示;在 iPhone 上默认用fullScreen方式显示,可是在 iOS8 后能够设置成popover的方式,在none中会进行解释
  • 默认状况下,点击灰色的背景popover会直接消失,经过presentedViewController.popoverPresentationController?.passthroughViews能够配置灰色背景的哪些视图区域能够点击

UIPopoverPresentationController的定义:

An object that manages the display of content in a popover.

当视图被用popover方式 present 的时候,总有一个popoverPresentationController的实例来管理呈现的行为。

popover
popover

none

  • 该枚举值不能够直接赋值给modalPresentationStyle
  • popoverPresentationController会调用它delegate的方法来配置popover的视图,none只能用在adaptivePresentationStyle(for:)代理方法中返回,告诉popoverPresentationController不要适配presentedViewController,这样在 iPhone 中也能够用popover的样式展现了

none
none
相关文章
相关标签/搜索