97 lines
2.5 KiB
Swift
97 lines
2.5 KiB
Swift
enum ModalPresentationStep: Int, CaseIterable {
|
|
case fullScreen
|
|
case halfScreen
|
|
case compact
|
|
case hidden
|
|
}
|
|
|
|
extension ModalPresentationStep {
|
|
private enum Constants {
|
|
static let iPadWidth: CGFloat = 350
|
|
static let compactHeightOffset: CGFloat = 120
|
|
static let halfScreenHeightFactorPortrait: CGFloat = 0.55
|
|
static let topInset: CGFloat = 8
|
|
}
|
|
|
|
var upper: ModalPresentationStep {
|
|
switch self {
|
|
case .fullScreen:
|
|
return .fullScreen
|
|
case .halfScreen:
|
|
return .fullScreen
|
|
case .compact:
|
|
return .halfScreen
|
|
case .hidden:
|
|
return .compact
|
|
}
|
|
}
|
|
|
|
var lower: ModalPresentationStep {
|
|
switch self {
|
|
case .fullScreen:
|
|
return .halfScreen
|
|
case .halfScreen:
|
|
return .compact
|
|
case .compact:
|
|
return .compact
|
|
case .hidden:
|
|
return .hidden
|
|
}
|
|
}
|
|
|
|
var first: ModalPresentationStep {
|
|
.fullScreen
|
|
}
|
|
|
|
var last: ModalPresentationStep {
|
|
.compact
|
|
}
|
|
|
|
func frame(for presentedView: UIView, in containerViewController: UIViewController) -> CGRect {
|
|
let isIPad = UIDevice.current.userInterfaceIdiom == .pad
|
|
var containerSize = containerViewController.view.bounds.size
|
|
if containerSize == .zero {
|
|
containerSize = UIScreen.main.bounds.size
|
|
}
|
|
let safeAreaInsets = containerViewController.view.safeAreaInsets
|
|
let traitCollection = containerViewController.traitCollection
|
|
var frame = CGRect(origin: .zero, size: containerSize)
|
|
|
|
if isIPad {
|
|
frame.size.width = Constants.iPadWidth
|
|
switch self {
|
|
case .hidden:
|
|
frame.origin.x = -Constants.iPadWidth
|
|
default:
|
|
frame.origin.x = .zero
|
|
}
|
|
return frame
|
|
}
|
|
|
|
let isPortraitOrientation = traitCollection.verticalSizeClass == .regular
|
|
if isPortraitOrientation {
|
|
switch self {
|
|
case .fullScreen:
|
|
frame.origin.y = safeAreaInsets.top + Constants.topInset
|
|
case .halfScreen:
|
|
frame.origin.y = containerSize.height * Constants.halfScreenHeightFactorPortrait
|
|
case .compact:
|
|
frame.origin.y = containerSize.height - Constants.compactHeightOffset
|
|
case .hidden:
|
|
frame.origin.y = containerSize.height
|
|
}
|
|
} else {
|
|
frame.size.width = Constants.iPadWidth
|
|
frame.origin.x = safeAreaInsets.left
|
|
switch self {
|
|
case .fullScreen:
|
|
frame.origin.y = Constants.topInset
|
|
case .halfScreen, .compact:
|
|
frame.origin.y = containerSize.height - Constants.compactHeightOffset
|
|
case .hidden:
|
|
frame.origin.y = containerSize.height
|
|
}
|
|
}
|
|
return frame
|
|
}
|
|
}
|