-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathActionSheetPresenter.swift
More file actions
119 lines (102 loc) · 4.75 KB
/
Copy pathActionSheetPresenter.swift
File metadata and controls
119 lines (102 loc) · 4.75 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
import UIKit
///
/// `ActionSheetPresenter` is a subcall of `UIPresentationController` that takes care of the
/// presentation logic of the `ActionSheet`
///
public class ActionSheetPresenter: UIPresentationController {
let backdropView: UIView!
let configuration: ActionSheetConfiguration
var tapGestureRecognizer: UITapGestureRecognizer = UITapGestureRecognizer()
@objc func dismiss() {
self.presentedViewController.dismiss(animated: true, completion: nil)
configuration.dismissCallback?()
}
public init(presentedViewController: UIViewController,
presenting presentingViewController: UIViewController?,
configuration: ActionSheetConfiguration) {
self.configuration = configuration
backdropView = UIView()
super.init(presentedViewController: presentedViewController,
presenting: presentingViewController)
tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(dismiss))
backdropView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
backdropView.isUserInteractionEnabled = true
backdropView.addGestureRecognizer(tapGestureRecognizer)
backdropView.backgroundColor = .black.withAlphaComponent(0.8)
}
public override var frameOfPresentedViewInContainerView: CGRect {
guard let containerView = containerView,
let presentedView = presentedView else { return .zero }
let safeAreaFrame = containerView.bounds
.inset(by: containerView.safeAreaInsets)
let targetWidth = safeAreaFrame.width
if let maxWidth = configuration.maxWidth {
let fittingSize = CGSize(
width: targetWidth,
height: UIView.layoutFittingCompressedSize.height
)
let tempSize = presentedView.systemLayoutSizeFitting(fittingSize,
withHorizontalFittingPriority: .defaultLow,
verticalFittingPriority: .defaultLow)
let contentSize = CGSize(width: min(tempSize.width, maxWidth),
height: min(tempSize.height, configuration.maxHeight))
let originX = floor((containerView.frame.width - contentSize.width) * 0.5)
return CGRect(
x: originX,
y: containerView.frame.height - contentSize.height,
width: contentSize.width,
height: contentSize.height
)
} else {
let fittingSize = CGSize(
width: targetWidth,
height: UIView.layoutFittingCompressedSize.height
)
let contentHeight = presentedView.systemLayoutSizeFitting(
fittingSize, withHorizontalFittingPriority: .required,
verticalFittingPriority: .defaultLow).height
let targetHeight = min(contentHeight, configuration.maxHeight)
return CGRect(
x: 0,
y: containerView.frame.height - targetHeight,
width: containerView.frame.width,
height: targetHeight
)
}
}
public override func dismissalTransitionWillBegin() {
presentedViewController.transitionCoordinator?.animate(
self.backdropView.alpha = 0,
completion: self.backdropView.removeFromSuperview()
)
}
public override func presentationTransitionWillBegin() {
backdropView.alpha = 0
containerView?.addSubview(backdropView)
presentedViewController.transitionCoordinator?.animate(
self.backdropView.alpha = 1
)
}
public override func containerViewWillLayoutSubviews() {
super.containerViewWillLayoutSubviews()
switch configuration.roundCornerStyle {
case .topCorner:
presentedView?.layer.cornerRadius = 8
presentedView?.layer.maskedCorners = [.layerMinXMinYCorner, .layerMaxXMinYCorner]
default:
presentedView?.layer.masksToBounds = true
presentedView?.layer.cornerRadius = 8
}
}
public override func containerViewDidLayoutSubviews() {
super.containerViewDidLayoutSubviews()
presentedView?.frame = frameOfPresentedViewInContainerView
backdropView.frame = containerView?.bounds ?? .zero
}
public override func preferredContentSizeDidChange(forChildContentContainer container: UIContentContainer) {
UIView.animate(withDuration: ActionSheetConstants.animationDuration) {
self.presentedView?.frame = self.frameOfPresentedViewInContainerView
}
super.preferredContentSizeDidChange(forChildContentContainer: container)
}
}