diff --git a/ios/RNIModalSheetView/RNIModalSheetViewDelegate.swift b/ios/RNIModalSheetView/RNIModalSheetViewDelegate.swift index d25192dd..5913821d 100644 --- a/ios/RNIModalSheetView/RNIModalSheetViewDelegate.swift +++ b/ios/RNIModalSheetView/RNIModalSheetViewDelegate.swift @@ -16,8 +16,13 @@ public final class RNIModalSheetViewDelegate: UIView, RNIContentView { case mainSheetContent; }; - public static var propKeyPathMap: Dictionary> { - return [:]; + public enum Events: String, CaseIterable { + case onModalWillPresent; + case onModalDidPresent; + case onModalWillShow; + case onModalDidShow; + case onModalWillHide; + case onModalDidHide; }; public enum Events: String, CaseIterable { @@ -58,8 +63,20 @@ public final class RNIModalSheetViewDelegate: UIView, RNIContentView { // MARK: - Methods // --------------- + func discardCurrentModalControllerIfNeeded(){ + guard let modalVC = self.modalSheetController, + !modalVC.isPresentedAsModal + else { + return; + }; + + self.modalSheetController = nil; + }; }; +// MARK: - RNIModalSheetViewDelegate+RNIContentViewDelegate +// -------------------------------------------------------- + extension RNIModalSheetViewDelegate: RNIContentViewDelegate { public typealias KeyPathRoot = RNIModalSheetViewDelegate; @@ -154,8 +171,24 @@ extension RNIModalSheetViewDelegate: RNIContentViewDelegate { modalVC.mainSheetContentParent = mainSheetContentParent; modalVC.view.backgroundColor = .systemBackground; + modalVC.lifecycleEventDelegates.add(self); + + self.dispatchEvent( + for: .onModalWillPresent, + withPayload: [ + "isAnimated": isAnimated, + ] + ); + + closestVC.present(modalVC, animated: isAnimated) { + self.dispatchEvent( + for: .onModalDidPresent, + withPayload: [ + "isAnimated": isAnimated, + ] + ); + }; - closestVC.present(modalVC, animated: isAnimated); resolveBlock([:]); case "dismissModal": @@ -169,7 +202,7 @@ extension RNIModalSheetViewDelegate: RNIContentViewDelegate { ); modalSheetController.dismiss(animated: isAnimated) { - self.modalSheetController = nil; + self.discardCurrentModalControllerIfNeeded(); }; resolveBlock([:]); @@ -201,3 +234,61 @@ extension RNIModalSheetViewDelegate: RNIContentViewDelegate { }; #endif }; + +// MARK: - RNIModalSheetViewDelegate+ViewControllerLifecycleNotifiable +// ------------------------------------------------------------------- + +extension RNIModalSheetViewDelegate: ViewControllerLifecycleNotifiable { + + public func notifyOnViewWillAppear( + sender: UIViewController, + isAnimated: Bool, + isFirstAppearance: Bool + ) { + self.dispatchEvent( + for: .onModalWillShow, + withPayload: [ + "isAnimated": isAnimated, + "isFirstAppearance": isFirstAppearance, + ] + ); + }; + + public func notifyOnViewDidAppear( + sender: UIViewController, + isAnimated: Bool, + isFirstAppearance: Bool + ) { + self.dispatchEvent( + for: .onModalDidShow, + withPayload: [ + "isAnimated": isAnimated, + "isFirstAppearance": isFirstAppearance, + ] + ); + }; + + public func notifyOnViewWillDisappear( + sender: UIViewController, + isAnimated: Bool + ) { + self.dispatchEvent( + for: .onModalWillHide, + withPayload: [ + "isAnimated": isAnimated, + ] + ); + }; + + public func notifyOnViewDidDisappear( + sender: UIViewController, + isAnimated: Bool + ) { + self.dispatchEvent( + for: .onModalDidHide, + withPayload: [ + "isAnimated": isAnimated, + ] + ); + }; +}; diff --git a/ios/RNIModalSheetView/RNIModalSheetViewManager.mm b/ios/RNIModalSheetView/RNIModalSheetViewManager.mm index 5eed26b5..35d13027 100644 --- a/ios/RNIModalSheetView/RNIModalSheetViewManager.mm +++ b/ios/RNIModalSheetView/RNIModalSheetViewManager.mm @@ -25,6 +25,18 @@ - (UIView *)view { return [[RNIModalSheetView new] initWithBridge:self.bridge]; } + +RNI_EXPORT_VIEW_EVENT(onDidSetViewID, RCTBubblingEventBlock) + +RNI_EXPORT_VIEW_EVENT(onModalWillPresent, RCTBubblingEventBlock); +RNI_EXPORT_VIEW_EVENT(onModalDidPresent, RCTBubblingEventBlock); + +RNI_EXPORT_VIEW_EVENT(onModalWillShow, RCTBubblingEventBlock); +RNI_EXPORT_VIEW_EVENT(onModalDidShow, RCTBubblingEventBlock); + +RNI_EXPORT_VIEW_EVENT(onModalWillHide, RCTBubblingEventBlock); +RNI_EXPORT_VIEW_EVENT(onModalDidHide, RCTBubblingEventBlock); + #endif @end diff --git a/src/types/CommonModalEvents.ts b/src/types/CommonModalEvents.ts index 1306724a..2aa68fe7 100644 --- a/src/types/CommonModalEvents.ts +++ b/src/types/CommonModalEvents.ts @@ -4,17 +4,31 @@ import type { BubblingEventHandler } from 'react-native/Libraries/Types/CodegenT // MARK: Event Objects // ------------------- -export type OnModalWillPresentPayload = Readonly<{}>; - -export type OnModalDidPresentEventPayload = Readonly<{}>; - -export type OnModalWillShowEventPayload = Readonly<{}>; - -export type OnModalDidShowEventPayload = Readonly<{}>; - -export type OnModalWillHideEventPayload = Readonly<{}>; - -export type OnModalDidHideEventPayload = Readonly<{}>; +export type OnModalWillPresentPayload = Readonly<{ + isAnimated: boolean; +}>; + +export type OnModalDidPresentEventPayload = Readonly<{ + isAnimated: boolean; +}>; + +export type OnModalWillShowEventPayload = Readonly<{ + isAnimated: boolean; + isFirstAppearance: boolean; +}>; + +export type OnModalDidShowEventPayload = Readonly<{ + isAnimated: boolean; + isFirstAppearance: boolean; +}>; + +export type OnModalWillHideEventPayload = Readonly<{ + isAnimated: boolean; +}>; + +export type OnModalDidHideEventPayload = Readonly<{ + isAnimated: boolean; +}>; // MARK: Events // ------------