Skip to content

Commit

Permalink
⭐️ Impl: ModalSheetViewControllerLifecycleNotifier
Browse files Browse the repository at this point in the history
  • Loading branch information
dominicstop committed Sep 27, 2024
1 parent c1d08e9 commit 711ae00
Showing 1 changed file with 226 additions and 0 deletions.
226 changes: 226 additions & 0 deletions ios/Temp/ModalSheetViewControllerLifecycleNotifier.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,226 @@
//
// ModalSheetViewControllerLifecycleNotifier.swift
// react-native-ios-modal
//
// Created by Dominic Go on 9/27/24.
//

import UIKit
import DGSwiftUtilities


open class ModalSheetViewControllerLifecycleNotifier: ViewControllerLifecycleNotifier {

private var _didSetup = false;

private(set) public var sheetLifecycleEventDelegates:
MulticastDelegate<SheetViewControllerEventsNotifiable> = .init();

/// The return value used for
/// `UIAdaptivePresentationControllerDelegate.presentationControllerShouldDismiss`
///
public var shouldAllowDismissal = true;

/// Will receive `UIAdaptivePresentationControllerDelegate` invocations
/// that were not handled by this class
///
public var presentationControllerDelegateProxy: UIAdaptivePresentationControllerDelegate?;

public weak var sheetGesture: UIPanGestureRecognizer?;
public weak var sheetDropShadowView: UIView?;

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

public override func viewDidLoad() {
super.viewDidLoad();
self.setupIfNeeded();
};

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

// MARK: - Setup
// -------------

public func setupIfNeeded(){
guard !self._didSetup,
let presentationController = self.presentationController
else {
return;
};

if presentationController.delegate != nil {
self.presentationControllerDelegateProxy = self;
};

self._setupSheetGesture();

presentationController.delegate = self;
self._didSetup = true;
};

private func _setupSheetGesture(){
guard let closestSheetPanGesture = self.closestSheetPanGesture else {
return;
};

closestSheetPanGesture.addTarget(
self,
action: #selector(Self._handleSheetGesture(_:))
);

self.sheetGesture = closestSheetPanGesture;
};

// MARK: - Methods
// ---------------

public override func addEventDelegate(_ delegate: AnyObject){
super.addEventDelegate(delegate);
guard let delegate = delegate as? SheetViewControllerEventsNotifiable else {
return;
};

self.sheetLifecycleEventDelegates.add(delegate);
};

@objc
private func _handleSheetGesture(_ panGesture: UIPanGestureRecognizer){
guard let presentationController = self.presentationController,
let presentedView = presentationController.presentedView
else {
return;
};

let gesturePoint = panGesture.translation(in: presentedView);

self.sheetLifecycleEventDelegates.invoke {
$0.notifyOnSytemSheetPanGestureInvoked(
sender: self,
panGesture: panGesture,
gesturePoint: gesturePoint
);
};
};
};

extension ModalSheetViewControllerLifecycleNotifier: UIAdaptivePresentationControllerDelegate {

public func adaptivePresentationStyle(
for controller: UIPresentationController
) -> UIModalPresentationStyle {

if let delegate = self.presentationControllerDelegateProxy,
let presentationStyle = delegate.adaptivePresentationStyle?(for: controller)
{
return presentationStyle;
};

return .pageSheet;
};

public func adaptivePresentationStyle(
for controller: UIPresentationController,
traitCollection: UITraitCollection
) -> UIModalPresentationStyle {

if let delegate = self.presentationControllerDelegateProxy,
let presentationStyle = delegate.adaptivePresentationStyle?(for: controller, traitCollection: traitCollection)
{
return presentationStyle;
};

return .none;
};

@available(iOS 15.0, *)
public func presentationController(
_ presentationController: UIPresentationController,
prepare adaptivePresentationController: UIPresentationController
) {
self.presentationControllerDelegateProxy?.presentationController?(
presentationController,
prepare: adaptivePresentationController
);
};

public func presentationController(
_ controller: UIPresentationController,
viewControllerForAdaptivePresentationStyle style: UIModalPresentationStyle
) -> UIViewController? {

return self.presentationControllerDelegateProxy?.presentationController?(
controller,
viewControllerForAdaptivePresentationStyle: style
);
};

public func presentationController(
_ presentationController: UIPresentationController,
willPresentWithAdaptiveStyle style: UIModalPresentationStyle,
transitionCoordinator: UIViewControllerTransitionCoordinator?
) {

self.presentationControllerDelegateProxy?.presentationController?(
presentationController,
willPresentWithAdaptiveStyle: style,
transitionCoordinator: transitionCoordinator
);
};

public func presentationControllerShouldDismiss(
_ presentationController: UIPresentationController
) -> Bool {

let shouldDismiss: Bool? =
self.presentationControllerDelegateProxy?.presentationControllerShouldDismiss?(presentationController);

return shouldDismiss ?? self.shouldAllowDismissal;
};

public func presentationControllerWillDismiss(
_ presentationController: UIPresentationController
) {
self.presentationControllerDelegateProxy?
.presentationControllerWillDismiss?(presentationController);

self.sheetLifecycleEventDelegates.invoke {
$0.notifyOnSheetWillDismissViaGesture(
sender: self,
presentationController: presentationController
);
};
};

public func presentationControllerDidDismiss(
_ presentationController: UIPresentationController
) {

self.presentationControllerDelegateProxy?
.presentationControllerDidDismiss?(presentationController);

self.sheetLifecycleEventDelegates.invoke {
$0.notifyOnSheetDidDismissViaGesture(
sender: self,
presentationController: presentationController
);
};
};

public func presentationControllerDidAttemptToDismiss(
_ presentationController: UIPresentationController
) {

self.presentationControllerDelegateProxy?
.presentationControllerDidAttemptToDismiss?(presentationController);

self.sheetLifecycleEventDelegates.invoke {
$0.notifyOnSheetDidAttemptToDismissViaGesture(
sender: self,
presentationController: presentationController
);
};
};
};

0 comments on commit 711ae00

Please sign in to comment.