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
相關文章
相關標籤/搜索