Skip to content

Commit

Permalink
⭐️ Impl: ModalViewControllerEventsNotifiable
Browse files Browse the repository at this point in the history
  • Loading branch information
dominicstop committed Sep 30, 2024
1 parent 8bfa246 commit 8e76eef
Show file tree
Hide file tree
Showing 4 changed files with 202 additions and 3 deletions.
8 changes: 5 additions & 3 deletions ios/Temp/ModalSheetViewControllerLifecycleNotifier.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import UIKit
import DGSwiftUtilities


open class ModalSheetViewControllerLifecycleNotifier: ViewControllerLifecycleNotifier {
open class ModalSheetViewControllerLifecycleNotifier: ModalViewControllerLifecycleNotifier {

private var _didSetup = false;
private var _didSetupRootScrollView = false;
Expand Down Expand Up @@ -56,11 +56,13 @@ open class ModalSheetViewControllerLifecycleNotifier: ViewControllerLifecycleNot
};

public override func viewDidAppear(_ animated: Bool) {
defer {
super.viewDidAppear(animated);
};

if self.isAppearingForTheFirstTime {
self.setupRootScrollViewIfNeeded();
};

super.viewDidAppear(animated);
};

// MARK: - Setup
Expand Down
66 changes: 66 additions & 0 deletions ios/Temp/ModalViewControllerEventsNotifiable.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
//
// ModalViewControllerEventsNotifiable.swift
// react-native-ios-modal
//
// Created by Dominic Go on 9/30/24.
//

import UIKit


public protocol ModalViewControllerEventsNotifiable {

func notifyOnModalWillPresent(
sender: UIViewController,
isAnimated: Bool
);

func notifyOnModalDidPresent(
sender: UIViewController,
isAnimated: Bool
);

func notifyOnModalWillDismiss(
sender: UIViewController,
isAnimated: Bool
);

func notifyOnModalDidDismiss(
sender: UIViewController,
isAnimated: Bool
);
};

// MARK: - ModalViewControllerEventsNotifiable
// -------------------------------------------

public extension ModalViewControllerEventsNotifiable {

func notifyOnModalWillPresent(
sender: UIViewController,
isAnimated: Bool
) {
// no-op
};

func notifyOnModalDidPresent(
sender: UIViewController,
isAnimated: Bool
) {
// no-op
};

func notifyOnModalWillDismiss(
sender: UIViewController,
isAnimated: Bool
) {
// no-op
};

func notifyOnModalDidDismiss(
sender: UIViewController,
isAnimated: Bool
) {
// no-op
};
};
126 changes: 126 additions & 0 deletions ios/Temp/ModalViewControllerLifecycleNotifier.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
//
// ModalViewControllerLifecycleNotifier.swift
// react-native-ios-modal
//
// Created by Dominic Go on 9/30/24.
//

import UIKit
import DGSwiftUtilities


open class ModalViewControllerLifecycleNotifier: ViewControllerLifecycleNotifier {

public var isExplicitlySomeKindOfModal = false;
public var isExplicitlyBeingDismissed = false;

private(set) public var modalLifecycleEventDelegates:
MulticastDelegate<ModalViewControllerEventsNotifiable> = .init();

// MARK: - View Controller Lifecycle
// ---------------------------------

public override func viewWillAppear(_ animated: Bool) {
defer {
super.viewWillAppear(animated);
};

guard self.isAppearingForTheFirstTime else {
return;
};

self.isExplicitlySomeKindOfModal =
self.isBeingPresented
|| self.presentingViewController?.presentedViewController === self;

guard self.isExplicitlySomeKindOfModal else {
return;
};

self.modalLifecycleEventDelegates.invoke {
$0.notifyOnModalWillPresent(
sender: self,
isAnimated: animated
);
};
};

public override func viewDidAppear(_ animated: Bool) {
defer {
super.viewDidAppear(animated);
};

guard self.isAppearingForTheFirstTime,
self.isExplicitlySomeKindOfModal
else {
return;
};

self.modalLifecycleEventDelegates.invoke {
$0.notifyOnModalDidPresent(
sender: self,
isAnimated: animated
);
};
};

public override func viewWillDisappear(_ animated: Bool) {
defer {
super.viewWillDisappear(animated);
};

guard self.isBeingDismissed,
self.isExplicitlySomeKindOfModal
else {
return;
};

guard animated,
let transitionCoordinator = self.transitionCoordinator
else {
self.isExplicitlyBeingDismissed = true;

self.modalLifecycleEventDelegates.invoke {
$0.notifyOnModalWillDismiss(
sender: self,
isAnimated: false
);
};
return;
};

transitionCoordinator.notifyWhenInteractionChanges { context in
guard !context.isCancelled else {
return;
};

self.isExplicitlyBeingDismissed = true;
self.modalLifecycleEventDelegates.invoke {
$0.notifyOnModalWillDismiss(
sender: self,
isAnimated: context.isAnimated
);
};
};
};

public override func viewDidDisappear(_ animated: Bool) {
defer {
super.viewDidDisappear(animated);
};

guard self.isBeingDismissed,
self.isExplicitlySomeKindOfModal,
self.isExplicitlyBeingDismissed
else {
return;
};

self.modalLifecycleEventDelegates.invoke {
$0.notifyOnModalDidDismiss(
sender: self,
isAnimated: animated
);
};
};
};
5 changes: 5 additions & 0 deletions ios/Temp/ViewControllerLifecycleNotifier.swift
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,14 @@ open class ViewControllerLifecycleNotifier: UIViewController {
"ViewControllerLifecycleNotifier.\(#function)",
"\n - instance:", Unmanaged.passUnretained(self).toOpaque(),
"\n - className:", self.className,
"\n - self:", self.debugDescription,
"\n - animated:", animated,
"\n - isBeingPresented:", self.isBeingPresented,
"\n - isAppearingForTheFirstTime:", self.isAppearingForTheFirstTime,
"\n - presentationController:", self.presentationController.debugDescription,
"\n - transitionCoordinator:", self.transitionCoordinator?.debugDescription ?? "N/A",
"\n - presentingViewController:", self.presentingViewController?.debugDescription ?? "N/A",
"\n - presentingViewController.presentedViewController:", self.presentingViewController?.presentedViewController.debugDescription ?? "N/A",
"\n"
);
};
Expand Down

0 comments on commit 8e76eef

Please sign in to comment.