From 5bb4fe864d832cb848d88b115c5dc0127f41a152 Mon Sep 17 00:00:00 2001 From: Dominic Go Date: Fri, 27 Sep 2024 19:51:38 +0800 Subject: [PATCH] =?UTF-8?q?=E2=AD=90=EF=B8=8F=20Impl:=20`ModalSheetPresent?= =?UTF-8?q?ationStateMachine`?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ModalSheetPresentationStateMachine.swift | 110 ++++++++++++++++++ ...SheetViewControllerLifecycleNotifier.swift | 5 + 2 files changed, 115 insertions(+) create mode 100644 ios/Temp/ModalSheetPresentationStateMachine.swift diff --git a/ios/Temp/ModalSheetPresentationStateMachine.swift b/ios/Temp/ModalSheetPresentationStateMachine.swift new file mode 100644 index 00000000..6025f27a --- /dev/null +++ b/ios/Temp/ModalSheetPresentationStateMachine.swift @@ -0,0 +1,110 @@ +// +// ModalSheetPresentationStateMachine.swift +// react-native-ios-modal +// +// Created by Dominic Go on 9/27/24. +// + +import UIKit +import DGSwiftUtilities + + +public class ModalSheetPresentationStateMachine { + + public var prevState: ModalSheetState?; + public var currentState: ModalSheetState = .dismissed; + + public var didPresent = false; + public var didDismissAfterPresented = false; + + public var eventDelegates: + MulticastDelegate = .init(); + + public func setStateExplicit(nextState: ModalSheetState){ + let prevState = self.prevState; + let currentState = self.currentState; + + self.prevState = self.currentState; + self.currentState = nextState; + + switch (prevState, currentState, nextState) { + case (_, let currentState, let nextState) + where !currentState.isPresented && nextState.isPresented: + + self.didPresent = true; + + case (_, let currentState, let nextState) where + !currentState.isPresented && nextState.isPresented: + + self.didDismissAfterPresented = true; + + default: + break; + }; + }; + + public func setState(nextState: ModalSheetState){ + switch (self.prevState, self.currentState, nextState) { + + default: + break; + }; + + self.setStateExplicit(nextState: nextState); + }; + + public func reset(){ + self.prevState = nil; + self.currentState = .dismissed; + + self.didPresent = false; + self.didDismissAfterPresented = false; + }; +}; + +extension ModalSheetPresentationStateMachine: ViewControllerLifecycleNotifiable { + + public func notifyOnViewDidLoad(sender: UIViewController) { + // no-op + }; + + public func notifyOnViewWillAppear( + sender: UIViewController, + isAnimated: Bool + ) { + + self.setState(nextState: .presenting); + }; + + public func notifyOnViewIsAppearing( + sender: UIViewController, + isAnimated: Bool + ) { + + self.setState(nextState: .presenting); + }; + + public func notifyOnViewDidAppear( + sender: UIViewController, + isAnimated: Bool + ) { + + self.setState(nextState: .presented); + }; + + public func notifyOnViewWillDisappear( + sender: UIViewController, + isAnimated: Bool + ) { + + self.setState(nextState: .dismissing); + }; + + public func notifyOnViewDidDisappear( + sender: UIViewController, + isAnimated: Bool + ) { + + self.setState(nextState: .dismissed); + }; +}; diff --git a/ios/Temp/ModalSheetViewControllerLifecycleNotifier.swift b/ios/Temp/ModalSheetViewControllerLifecycleNotifier.swift index 07bb7980..c51ea849 100644 --- a/ios/Temp/ModalSheetViewControllerLifecycleNotifier.swift +++ b/ios/Temp/ModalSheetViewControllerLifecycleNotifier.swift @@ -28,6 +28,9 @@ open class ModalSheetViewControllerLifecycleNotifier: ViewControllerLifecycleNot public weak var sheetGesture: UIPanGestureRecognizer?; public weak var sheetDropShadowView: UIView?; + + public var sheetPresentationStateMachine: + ModalSheetPresentationStateMachine = .init(); // MARK: - View Controller Lifecycle // --------------------------------- @@ -56,6 +59,8 @@ open class ModalSheetViewControllerLifecycleNotifier: ViewControllerLifecycleNot self.presentationControllerDelegateProxy = self; }; + self.lifecycleEventDelegates.add(self.sheetPresentationStateMachine); + presentationController.delegate = self; self._didSetup = true; };