Skip to content

Commit

Permalink
💫 Update: Exp - AdaptiveModal
Browse files Browse the repository at this point in the history
Summary: Update experiment/test - `swift-programmatic-modal/AdaptiveModal`.
  • Loading branch information
dominicstop committed May 26, 2023
1 parent 9932f39 commit 3836b43
Show file tree
Hide file tree
Showing 3 changed files with 83 additions and 80 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,14 @@ struct AdaptiveModalConfig {
let snapDirection: Direction;

// let entranceConfig: AdaptiveModalEntranceConfig;
let snapSwipeVelocityThreshold: CGFloat = 0;
// let snappingAnimationConfig enum

init(
snapPoints: [AdaptiveModalSnapPointConfig],
snapDirection: Direction
) {
self.snapPoints = snapPoints
self.snapDirection = snapDirection
}
};
Original file line number Diff line number Diff line change
Expand Up @@ -70,9 +70,12 @@ class AdaptiveModalManager {
var targetRectProvider: () -> CGRect;
var currentSizeProvider: () -> CGSize;

var gestureOffset: CGFloat?;
weak var targetView: UIView?;
weak var modalView: UIView?;

var gestureOffset: CGFloat?;
var gestureVelocity: CGFloat?;

// MARK: - Computed Properties
// ---------------------------

Expand Down Expand Up @@ -107,18 +110,79 @@ class AdaptiveModalManager {
// ------------

init(
modalView: UIView,
targetView: UIView,
targetRectProvider: @escaping () -> CGRect,
currentSizeProvider: @escaping () -> CGSize,
modalView: UIView
currentSizeProvider: @escaping () -> CGSize
){
self.targetRectProvider = targetRectProvider;
self.currentSizeProvider = currentSizeProvider;

self.modalView = modalView;
self.targetView = targetView;
};

// MARK: - Functions
// -----------------

func setFrameForModal(){
guard let modalView = self.modalView else { return };

let currentSnapPoint = self.currentSnapPointConfig.snapPoint;

modalView.frame = currentSnapPoint.computeRect(
withTargetRect: self.targetRectProvider(),
currentSize: self.currentSizeProvider()
);
};

func animateModal(toRect nextRect: CGRect) {
guard let modalView = self.modalView else { return };

let animator = UIViewPropertyAnimator(
duration: 0.2,
curve: .easeIn
);

animator.addAnimations {
modalView.frame = nextRect;
};

animator.startAnimation();
};

func notifyOnDragPanGesture(_ gesture: UIPanGestureRecognizer){
guard let modalView = self.modalView else { return };

let gesturePoint = gesture.location(in: self.targetView);

switch gesture.state {
case .began:
break;

case .cancelled, .ended:
self.gestureOffset = nil;

let nextSnapPoint = self.getNextSnapPoint(
forRect: modalView.frame
);

self.animateModal(toRect: nextSnapPoint.computedRect);
self.currentSnapPointIndex = nextSnapPoint.nextSnapPointIndex;
break;

case .changed:
let computedRect = self.interpolateModalRect(
forGesturePoint: gesturePoint
);

modalView.frame = computedRect;

default:
break;
};
};

func getNextSnapPoint(
forRect currentRect: CGRect
) -> (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,14 @@ import UIKit
class RNIDraggableTestViewController : UIViewController {

lazy var modalManager = AdaptiveModalManager(
modalView: self.floatingView,
targetView: self.view,
targetRectProvider: { [unowned self] in
self.view.frame;
},
currentSizeProvider: {
.zero
},
modalView: self.floatingView
}
);

private var initialGesturePoint: CGPoint = .zero;
Expand Down Expand Up @@ -79,89 +80,17 @@ class RNIDraggableTestViewController : UIViewController {
let floatingView = self.floatingView;
self.view.addSubview(floatingView);

let initialSnapPointConfig = self.modalManager.currentSnapPointConfig;
let initialSnapPoint = initialSnapPointConfig.snapPoint;

let computedRect = initialSnapPoint.computeRect(
withTargetRect: self.view.frame,
currentSize: CGSize(width: 300, height: 300)
);

self.floatingView.frame = computedRect;
self.floatingViewLabel.text = "\(self.modalManager.currentSnapPointIndex)";

self.modalManager.setFrameForModal();
};

func updateFloatingView(
nextFrame: CGRect,
isAnimated: Bool = false
) {

let animationBlock = {
self.floatingView.frame = nextFrame;
self.floatingViewLabel.text = "\(self.modalManager.currentSnapPointIndex)";
};

if isAnimated {
let animator = UIViewPropertyAnimator(
duration:0.2,
curve: .easeIn,
animations: animationBlock
);

animator.startAnimation();

} else {
animationBlock();
};
};


@objc func onPressFloatingViewLabel(_ sender: UITapGestureRecognizer){
// self.layoutConfigCount += 1;
// self.updateFloatingView(isAnimated: true);
};

@objc func onDragPanGestureView(_ sender: UIPanGestureRecognizer) {
let floatingView = self.floatingView;

let gesturePoint = sender.location(in: self.view);
let relativeGesturePoint = sender.translation(in: self.view);

print(
"onDragPanGestureView"
+ "\n" + " - sender.state: \(sender.state)"
+ "\n" + " - gesturePoint: \(gesturePoint)"
+ "\n"
);

switch sender.state {
case .began:
self.floatingViewInitialCenter = floatingView.center;
self.initialGesturePoint = gesturePoint;

case .cancelled, .ended:
self.modalManager.gestureOffset = nil;

let currentRect = self.floatingView.frame;

let nextSnapPoint =
self.modalManager.getNextSnapPoint(forRect: currentRect);

self.updateFloatingView(
nextFrame: nextSnapPoint.computedRect,
isAnimated: true
);
break;

case .changed:
let computedRect = self.modalManager.interpolateModalRect(
forGesturePoint: gesturePoint
);

floatingView.frame = computedRect;

default:
break;
};
self.modalManager.notifyOnDragPanGesture(sender);
};
};

0 comments on commit 3836b43

Please sign in to comment.