diff --git a/experiments/swift-programmatic-modal/AdaptiveModal/AdaptiveModalManager+UIViewControllerAnimatedTransitioning.swift b/experiments/swift-programmatic-modal/AdaptiveModal/AdaptiveModalManager+UIViewControllerAnimatedTransitioning.swift index e4567305..b689c435 100644 --- a/experiments/swift-programmatic-modal/AdaptiveModal/AdaptiveModalManager+UIViewControllerAnimatedTransitioning.swift +++ b/experiments/swift-programmatic-modal/AdaptiveModal/AdaptiveModalManager+UIViewControllerAnimatedTransitioning.swift @@ -19,32 +19,6 @@ extension AdaptiveModalManager: UIViewControllerAnimatedTransitioning { func animateTransition( using transitionContext: UIViewControllerContextTransitioning ) { - guard let fromViewController = transitionContext.viewController(forKey: .from), - let toViewController = transitionContext.view(forKey: .to) - else { return }; - - self.targetView = transitionContext.containerView; - - self.currentInterpolationIndex = 1; - - self.computeSnapPoints(); - - self.setupInitViews(); - self.setupDummyModalView(); - self.setupGestureHandler(); - - self.setupAddViews(); - self.setupViewConstraints(); - - self.updateModal(); - - print( - "transitionContext" - + "\n - containerView: \(transitionContext.containerView)" - + "\n - modalView: + \(self.modalView)" - + "\n - targetView: + \(self.targetView)" - + "\n - currentInterpolationIndex: + \(self.currentInterpolationIndex)" - + "\n - currentInterpolationStep: + \(self.currentInterpolationStep)" - ); + //TBA }; }; diff --git a/experiments/swift-programmatic-modal/AdaptiveModal/AdaptiveModalManager.swift b/experiments/swift-programmatic-modal/AdaptiveModal/AdaptiveModalManager.swift index 0fa94d8c..728a1a86 100644 --- a/experiments/swift-programmatic-modal/AdaptiveModal/AdaptiveModalManager.swift +++ b/experiments/swift-programmatic-modal/AdaptiveModal/AdaptiveModalManager.swift @@ -7,7 +7,7 @@ import UIKit -class AdaptiveModalManager: NSObject, UIGestureRecognizerDelegate { +class AdaptiveModalManager: NSObject { // MARK: - Properties - Config-Related // ------------------------------------ @@ -222,6 +222,9 @@ class AdaptiveModalManager: NSObject, UIGestureRecognizerDelegate { super.init(); self.computeSnapPoints(); + self.setupViewControllers(); + self.setupInitViews(); + self.setupDummyModalView(); }; deinit { @@ -231,15 +234,31 @@ class AdaptiveModalManager: NSObject, UIGestureRecognizerDelegate { // MARK: - Functions - Setup // ------------------------- - func setupInitViews(){ - //self.modalBackgroundView = UIView(); - //self.modalBackgroundVisualEffectView = UIVisualEffectView(); + private func setupViewControllers() { + modalViewController?.modalPresentationStyle = .custom; + modalViewController?.transitioningDelegate = self; + }; + + private func setupInitViews(){ + self.modalBackgroundView = UIView(); + self.modalBackgroundVisualEffectView = UIVisualEffectView(); self.backgroundDimmingView = UIView(); self.backgroundVisualEffectView = UIVisualEffectView(); }; - func setupDummyModalView(){ + private func setupGestureHandler(){ + guard let modalView = self.modalView else { return }; + + modalView.addGestureRecognizer( + UIPanGestureRecognizer( + target: self, + action: #selector(self.onDragPanGesture(_:)) + ) + ); + }; + + private func setupDummyModalView(){ guard let targetView = self.targetView else { return }; let dummyModalView = self.dummyModalView; @@ -250,7 +269,7 @@ class AdaptiveModalManager: NSObject, UIGestureRecognizerDelegate { targetView.addSubview(dummyModalView); }; - func setupAddViews(){ + private func setupAddViews(){ guard let modalView = self.modalView, let targetView = self.targetView else { return }; @@ -275,7 +294,6 @@ class AdaptiveModalManager: NSObject, UIGestureRecognizerDelegate { modalView.clipsToBounds = true; modalView.backgroundColor = .clear; - modalWrapperView.addSubview(modalView); if let modalBackgroundView = self.modalBackgroundView { @@ -291,11 +309,12 @@ class AdaptiveModalManager: NSObject, UIGestureRecognizerDelegate { modalView.sendSubviewToBack(modalBGVisualEffectView); modalBGVisualEffectView.clipsToBounds = true; + modalBGVisualEffectView.backgroundColor = .clear; modalBGVisualEffectView.isUserInteractionEnabled = false; }; }; - func setupViewConstraints(){ + private func setupViewConstraints(){ guard let modalView = self.modalView, let targetView = self.targetView else { return }; @@ -353,29 +372,6 @@ class AdaptiveModalManager: NSObject, UIGestureRecognizerDelegate { ]); }; }; - - func setupGestureHandler(){ - guard let modalView = self.modalView else { return }; - - let gesture = UIPanGestureRecognizer( - target: self, - action: #selector(Self.onDragPanGesture(_:)) - ); - - gesture.isEnabled = true; - gesture.minimumNumberOfTouches = 1; - gesture.maximumNumberOfTouches = 1; - gesture.delegate = self; - - modalView.addGestureRecognizer(gesture); - modalView.isUserInteractionEnabled = true; - modalView.backgroundColor = .systemBackground; - }; - - func setupViewControllers() { - modalViewController?.modalPresentationStyle = .custom; - modalViewController?.transitioningDelegate = self; - }; // MARK: - Functions - Interpolation-Related Helpers // ------------------------------------------------- @@ -1023,13 +1019,6 @@ class AdaptiveModalManager: NSObject, UIGestureRecognizerDelegate { return nextIndex; }; - public func gestureRecognizer( - _ gestureRecognizer: UIGestureRecognizer, - shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer - ) -> Bool { - return true; - }; - @objc func onDragPanGesture(_ sender: UIPanGestureRecognizer) { let gesturePoint = sender.location(in: self.targetView); self.gesturePoint = gesturePoint; @@ -1131,7 +1120,18 @@ class AdaptiveModalManager: NSObject, UIGestureRecognizerDelegate { // MARK: - User-Invoked Functions // ------------------------------ - + + func computeSnapPoints( + usingLayoutValueContext context: RNILayoutValueContext? = nil + ) { + let context = context ?? self.layoutValueContext; + + self.rawInterpolationSteps = .Element.compute( + usingModalConfig: self.modalConfig, + layoutValueContext: context + ); + }; + func prepareForPresentation( modalView: UIView, targetView: UIView @@ -1139,40 +1139,15 @@ class AdaptiveModalManager: NSObject, UIGestureRecognizerDelegate { self.modalView = modalView; self.targetView = targetView; - modalView.isUserInteractionEnabled = true; - + self.computeSnapPoints(); + self.setupInitViews(); self.setupDummyModalView(); + self.setupGestureHandler(); self.setupAddViews(); self.setupViewConstraints(); - self.setupGestureHandler(); - - self.computeSnapPoints(); self.updateModal(); - - modalView.frame = self.modalWrapperView.frame; - }; - - func showModal( - completion: ((UIViewAnimatingPosition) -> Void)? = nil - ){ - self.currentInterpolationIndex = self.modalConfig.initialSnapPointIndex; - self.animateModal( - to: self.currentInterpolationStep, - completion: completion - ); - }; - - func computeSnapPoints( - usingLayoutValueContext context: RNILayoutValueContext? = nil - ) { - let context = context ?? self.layoutValueContext; - - self.rawInterpolationSteps = .Element.compute( - usingModalConfig: self.modalConfig, - layoutValueContext: context - ); }; func updateModal(){ @@ -1188,10 +1163,6 @@ class AdaptiveModalManager: NSObject, UIGestureRecognizerDelegate { }; }; - func snapToCurrentIndex(){ - self.animateModal(to: self.currentInterpolationStep); - }; - func snapToClosestSnapPoint( forPoint point: CGPoint, duration: CGFloat? = nil, @@ -1257,6 +1228,29 @@ class AdaptiveModalManager: NSObject, UIGestureRecognizerDelegate { ); }; + func snapToCurrentIndex(){ + self.animateModal(to: self.currentInterpolationStep); + }; + + func showModal( + completion: ((UIViewAnimatingPosition) -> Void)? = nil + ) { + let prevIndex = self.currentInterpolationIndex; + let nextIndex = self.modalConfig.initialSnapPointIndex; + + self.nextInterpolationIndex = nextIndex; + self.onModalWillSnap(); + + let nextPoint = self.interpolationSteps[nextIndex]; + + self.animateModal(to: nextPoint) { [unowned self] in + self.currentInterpolationIndex = nextIndex; + self.onModalDidSnap(); + + completion?($0); + }; + }; + // MARK: - Event Functions // ----------------------- diff --git a/experiments/swift-programmatic-modal/Test/AdaptiveModalPresentationTestViewController.swift b/experiments/swift-programmatic-modal/Test/AdaptiveModalPresentationTestViewController.swift index a8602c4d..71841197 100644 --- a/experiments/swift-programmatic-modal/Test/AdaptiveModalPresentationTestViewController.swift +++ b/experiments/swift-programmatic-modal/Test/AdaptiveModalPresentationTestViewController.swift @@ -68,14 +68,8 @@ class AdaptiveModalPresentationTestViewController : UIViewController { }; @objc func onPressButtonPresentViewController(_ sender: UIButton) { - let testVC = TestViewController(); - - let manager = self.adaptiveModalManager; - manager.modalViewController = testVC; - manager.modalView = testVC.view; - manager.setupViewControllers(); - + self.present(testVC, animated: true); }; }; diff --git a/experiments/swift-programmatic-modal/Test/RNIDraggableTestViewController.swift b/experiments/swift-programmatic-modal/Test/RNIDraggableTestViewController.swift index 1bb7ed6b..4cf96113 100644 --- a/experiments/swift-programmatic-modal/Test/RNIDraggableTestViewController.swift +++ b/experiments/swift-programmatic-modal/Test/RNIDraggableTestViewController.swift @@ -325,7 +325,9 @@ enum AdaptiveModalConfigTestPresets: CaseIterable { class RNIDraggableTestViewController : UIViewController { - var modalManager: AdaptiveModalManager?; + lazy var modalManager = AdaptiveModalManager( + modalConfig: AdaptiveModalConfigTestPresets.default.config + ); private var initialGesturePoint: CGPoint = .zero; private var floatingViewInitialCenter: CGPoint = .zero @@ -333,7 +335,7 @@ class RNIDraggableTestViewController : UIViewController { lazy var floatingViewLabel: UILabel = { let label = UILabel(); - label.text = "\(self.modalManager?.currentSnapPointIndex ?? -1)"; + label.text = "\(self.modalManager.currentSnapPointIndex)"; label.textColor = #colorLiteral(red: 0, green: 0, blue: 0, alpha: 0.5); label.font = .boldSystemFont(ofSize: 22); @@ -440,27 +442,14 @@ class RNIDraggableTestViewController : UIViewController { }; @objc func onPressButtonPresentViewController(_ sender: UIButton){ - let manager = AdaptiveModalManager( - modalConfig: AdaptiveModalConfigTestPresets.default.config - ); + self.modalManager.eventDelegate = self; - manager.prepareForPresentation( + self.modalManager.prepareForPresentation( modalView: self.floatingView, targetView: self.view ); - - manager.showModal(){ _ in - manager.setupGestureHandler(); - } - - print( - "onPressButtonPresentViewController" - + "\n - floatingView.superview: \(self.floatingView.superview)" - + "\n - floatingView: \(self.floatingView)" - + "\n - manager.modalWrapperView: \(manager.modalWrapperView)" - + "\n - manager.modalWrapperView.subviews: \(manager.modalWrapperView.subviews)" - + "\n - manager.modalWrapperView.subviews.first!.subviews: \(manager.modalWrapperView.subviews.first!.subviews)" - ); + + self.modalManager.showModal(); }; };