@@ -12,11 +12,65 @@ final class EKWindowProvider: EntryPresenterDelegate, EKProvider {
1212
1313 /** The artificial safe area insets */
1414 var safeAreaInsets : UIEdgeInsets {
15- return entryWindow? . rootViewController? . view? . safeAreaInsets ?? UIApplication . shared. keyWindow? . rootViewController? . view. safeAreaInsets ?? . zero
15+ return EKWindowProvider . provider ( for : . normal ) . entryWindow? . rootViewController? . view? . safeAreaInsets ?? UIApplication . shared. keyWindow? . rootViewController? . view. safeAreaInsets ?? . zero
1616 }
1717
18+ private static var providers : [ UIWindow . Level : EKWindowProvider ] = [ : ]
19+
1820 /** Single access point */
19- static let shared = EKWindowProvider ( )
21+ static func provider( for level: UIWindow . Level ) -> EKWindowProvider {
22+ if let provider = providers [ level] {
23+ return provider
24+ } else {
25+ let provider = EKWindowProvider ( level: level)
26+ providers [ level] = provider
27+ return provider
28+ }
29+ }
30+
31+ static var topMostProvider : EKWindowProvider ? {
32+ if let topMostLevel = providers. keys. sorted ( by: { $0 > $1 } ) . first {
33+ return provider ( for: topMostLevel)
34+ }
35+ return nil
36+ }
37+
38+ static func isCurrentlyDisplaying( entryNamed name: String ? = nil ) -> Bool {
39+ for provider in providers. values
40+ where provider. isCurrentlyDisplaying ( entryNamed: name) {
41+ return true
42+ }
43+ return false
44+ }
45+
46+ static func queueContains( entryNamed name: String ? = nil ) -> Bool {
47+ for provider in providers. values
48+ where provider. queueContains ( entryNamed: name) {
49+ return true
50+ }
51+ return false
52+ }
53+
54+ static func dismiss( _ descriptor: SwiftEntryKit . EntryDismissalDescriptor , with completion: SwiftEntryKit . DismissCompletionHandler ? = nil ) {
55+
56+ switch descriptor {
57+ case . displayed:
58+ topMostProvider? . rootVC? . animateOutLastEntry ( completionHandler: completion)
59+ default :
60+ let dispatchGroup = DispatchGroup ( )
61+ for provider in providers. values {
62+ dispatchGroup. enter ( )
63+ provider. dismiss ( descriptor) {
64+ dispatchGroup. leave ( )
65+ }
66+ }
67+ dispatchGroup. notify ( queue: . main, execute: completion ?? { } )
68+ }
69+ }
70+
71+ static func layoutIfNeeded( ) {
72+ providers. values. forEach { $0. layoutIfNeeded ( ) }
73+ }
2074
2175 /** Current entry window */
2276 var entryWindow : EKWindow !
@@ -37,8 +91,12 @@ final class EKWindowProvider: EntryPresenterDelegate, EKProvider {
3791
3892 private weak var entryView : EKEntryView !
3993
94+ private let windowLevel : UIWindow . Level
95+
4096 /** Cannot be instantiated, customized, inherited */
41- private init ( ) { }
97+ private init ( level: UIWindow . Level ) {
98+ windowLevel = level
99+ }
42100
43101 var isResponsiveToTouches : Bool {
44102 set {
@@ -59,7 +117,6 @@ final class EKWindowProvider: EntryPresenterDelegate, EKProvider {
59117 }
60118 entryVC. setStatusBarStyle ( for: attributes)
61119
62- entryWindow. windowLevel = attributes. windowLevel. value
63120 if presentInsideKeyWindow {
64121 entryWindow. makeKeyAndVisible ( )
65122 } else {
@@ -74,7 +131,7 @@ final class EKWindowProvider: EntryPresenterDelegate, EKProvider {
74131 let entryVC : EKRootViewController
75132 if entryWindow == nil {
76133 entryVC = EKRootViewController ( with: self )
77- entryWindow = EKWindow ( with: entryVC)
134+ entryWindow = EKWindow ( with: entryVC, level : windowLevel )
78135 mainRollbackWindow = UIApplication . shared. keyWindow
79136 } else {
80137 entryVC = rootVC!
@@ -146,6 +203,9 @@ final class EKWindowProvider: EntryPresenterDelegate, EKProvider {
146203
147204 /** Clear all entries immediately and display to the rollback window */
148205 func displayRollbackWindow( ) {
206+ defer {
207+ EKWindowProvider . providers. removeValue ( forKey: windowLevel)
208+ }
149209 if #available( iOS 13 . 0 , * ) {
150210 entryWindow. windowScene = nil
151211 }
0 commit comments