From 70af749a8c12df9fce016d7da8f0dc0127dcca9b Mon Sep 17 00:00:00 2001 From: "Tomasz K." Date: Sun, 4 Aug 2024 02:59:32 +0200 Subject: [PATCH] Patch 2.6.0 feat: - Added onDismiss modifier --- MijickPopupView.podspec | 4 ++-- Sources/Internal/Managers/PopupManager.swift | 13 ++++++++++++- Sources/Public/Extensions/Public+Popup.swift | 5 ++++- 3 files changed, 18 insertions(+), 4 deletions(-) diff --git a/MijickPopupView.podspec b/MijickPopupView.podspec index 2d63b25d64..674a81fa28 100644 --- a/MijickPopupView.podspec +++ b/MijickPopupView.podspec @@ -5,9 +5,9 @@ Pod::Spec.new do |s| PopupView is a free and open-source library dedicated for SwiftUI that makes the process of presenting popups easier and much cleaner. DESC - s.version = '2.5.1' + s.version = '2.6.0' s.ios.deployment_target = '14.0' - s.osx.deployment_target = '12.0' + s.osx.deployment_target = '13.0' s.swift_version = '5.0' s.source_files = 'Sources/**/*' diff --git a/Sources/Internal/Managers/PopupManager.swift b/Sources/Internal/Managers/PopupManager.swift index c99e528d9d..1e121555dc 100644 --- a/Sources/Internal/Managers/PopupManager.swift +++ b/Sources/Internal/Managers/PopupManager.swift @@ -11,14 +11,24 @@ import SwiftUI public class PopupManager: ObservableObject { - @Published private(set) var views: [any Popup] = [] + @Published private(set) var views: [any Popup] = [] { willSet { onViewsChanged(newValue) }} private(set) var presenting: Bool = true private(set) var popupsWithoutOverlay: [ID] = [] private(set) var popupsToBeDismissed: [ID: DispatchSourceTimer] = [:] + private(set) var popupActionsOnDismiss: [ID: () -> ()] = [:] static let shared: PopupManager = .init() private init() {} } +private extension PopupManager { + func onViewsChanged(_ newViews: [any Popup]) { newViews + .difference(from: views, by: { $0.id == $1.id }) + .forEach { switch $0 { + case .remove(_, let element, _): popupActionsOnDismiss[element.id]?(); popupActionsOnDismiss.removeValue(forKey: element.id) + default: return + }} + } +} // MARK: - Operations enum StackOperation { @@ -33,6 +43,7 @@ extension PopupManager { }} static func dismissPopupAfter(_ popup: any Popup, _ seconds: Double) { shared.popupsToBeDismissed[popup.id] = DispatchSource.createAction(deadline: seconds) { performOperation(.remove(popup.id)) } } static func hideOverlay(_ popup: any Popup) { shared.popupsWithoutOverlay.append(popup.id) } + static func onPopupDismiss(_ popup: any Popup, _ action: @escaping () -> ()) { shared.popupActionsOnDismiss[popup.id] = action } } private extension PopupManager { static func removePopupFromStackToBeDismissed(_ operation: StackOperation) { switch operation { diff --git a/Sources/Public/Extensions/Public+Popup.swift b/Sources/Public/Extensions/Public+Popup.swift index bdf4e08f1a..8484c16457 100644 --- a/Sources/Public/Extensions/Public+Popup.swift +++ b/Sources/Public/Extensions/Public+Popup.swift @@ -27,8 +27,11 @@ public extension Popup { /// Hides the overlay for the selected popup @discardableResult func hideOverlay() -> some Popup { PopupManager.hideOverlay(self); return self } - /// Supplies an observable object to a view’s hierarchy. + /// Supplies an observable object to a view’s hierarchy @discardableResult func environmentObject(_ object: T) -> any Popup { AnyPopup(self, object) } + + /// Action to be executed after popups is dismissed + @discardableResult func onDismiss(_ action: @escaping () -> ()) -> any Popup { PopupManager.onPopupDismiss(self, action); return self } } // MARK: - Available Popups