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 Jun 19, 2023
1 parent 8c41cf0 commit a06f80b
Show file tree
Hide file tree
Showing 7 changed files with 99 additions and 67 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,6 @@ struct AdaptiveModalConfig {

let snapPercentStrategy: SnapPercentStrategy;

// let snapPointInitial:

let snapAnimationConfig: AdaptiveModalSnapAnimationConfig;
let interpolationClampingConfig: AdaptiveModalClampingConfig;

Expand All @@ -49,7 +47,6 @@ struct AdaptiveModalConfig {
overshootSnapPoint: self.overshootSnapPoint
);
};


var overshootSnapPointIndex: Int {
self.snapPoints.count - 1;
Expand Down Expand Up @@ -112,7 +109,7 @@ struct AdaptiveModalConfig {
self.initialSnapPointIndex = initialSnapPointIndex;

self.undershootSnapPoint = undershootSnapPoint
?? .getDefaultInitialSnapPoint(forDirection: snapDirection);
?? .getDefaultUnderShootSnapPoint(forDirection: snapDirection);

self.overshootSnapPoint = overshootSnapPoint
?? .getDefaultOvershootSnapPoint(forDirection: snapDirection);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ class AdaptiveModalManager: NSObject {
var modalConfig: AdaptiveModalConfig;

var enableSnapping = true;
var enableOverShooting = true;

var shouldSnapToUnderShootSnapPoint = true;
var shouldSnapToOvershootSnapPoint = false;
Expand Down Expand Up @@ -282,7 +283,7 @@ class AdaptiveModalManager: NSObject {
func setupViewControllers() {
guard let modalVC = self.modalViewController else { return };

modalVC.modalPresentationStyle = .custom;
modalVC.modalPresentationStyle = .overCurrentContext;
modalVC.transitioningDelegate = self;
};

Expand Down Expand Up @@ -979,10 +980,19 @@ class AdaptiveModalManager: NSObject {

let percent = inputValue / interpolationRangeMaxInput;

let percentAdj = shouldInvertPercent
? AdaptiveModalUtilities.invertPercent(percent)
: percent;
let percentClamped: CGFloat = {
guard !self.enableOverShooting else { return percent };

let secondToLastIndex = self.modalConfig.overshootSnapPointIndex - 1;
let maxPercent = self.interpolationRangeInput[secondToLastIndex];

return percent.clamped(max: maxPercent);
}();

let percentAdj = shouldInvertPercent
? AdaptiveModalUtilities.invertPercent(percentClamped)
: percentClamped;

self.applyInterpolationToModal(forInputPercentValue: percentAdj);
};

Expand Down Expand Up @@ -1112,21 +1122,6 @@ class AdaptiveModalManager: NSObject {
let interpolationPoint = interpolationSteps[closestInterpolationIndex];
let snapPointIndex = interpolationPoint.snapPointIndex;

let coords = self.interpolationSteps.map {
$0.computedRect[keyPath: self.modalConfig.inputValueKeyForRect];
};

print(
"getClosestSnapPoint"
+ "\n - inputRect: \(inputRect)"
+ "\n - inputCoordAdj: \(inputCoordAdj)"
+ "\n - coords: \(coords)"
+ "\n - delta: \(delta)"
+ "\n - deltaSorted: \(deltaSorted)"
+ "\n - closestInterpolationIndex: \(closestInterpolationIndex)"
+ "\n"
);

return (
interpolationIndex: closestInterpolationIndex,
snapPointConfig: self.modalConfig.snapPoints[snapPointIndex],
Expand Down Expand Up @@ -1291,15 +1286,6 @@ class AdaptiveModalManager: NSObject {
let gestureFinalPoint =
self.applyGestureOffsets(forGesturePoint: gestureFinalPointRaw);

print(
"onDragPanGesture"
+ "\n - gesturePoint: \(gesturePoint)"
+ "\n - gestureVelocity: \(gestureVelocity)"
+ "\n - gestureFinalPointRaw: \(gestureFinalPointRaw)"
+ "\n - gestureFinalPoint: \(gestureFinalPoint)"
+ "\n"
);

self.snapToClosestSnapPoint(forPoint: gestureFinalPoint) {
self.notifyOnModalDidSnap();
};
Expand Down Expand Up @@ -1430,9 +1416,14 @@ class AdaptiveModalManager: NSObject {
let shouldDismiss =
shouldDismissOnSnapToUnderShootSnapPoint ||
shouldDismissOnSnapToOverShootSnapPoint;


let isPresenting = self.currentInterpolationIndex == 0 && nextIndex == 1;

if shouldDismiss {
self.notifyOnModalWillHide();

} else if isPresenting {
self.notifyOnModalWillShow();
};
};

Expand All @@ -1458,16 +1449,34 @@ class AdaptiveModalManager: NSObject {
let shouldDismiss =
shouldDismissOnSnapToUnderShootSnapPoint ||
shouldDismissOnSnapToOverShootSnapPoint;

let wasPresented =
self.currentInterpolationIndex == 1 && self.prevInterpolationIndex == 0;

if shouldDismiss {
self.notifyOnModalDidHide();

} else if wasPresented {
self.notifyOnModalDidShow();
};

self.debug();
};

private func notifyOnModalWillShow(){
// wip
};

private func notifyOnModalDidShow(){
// wip
//UIView.animate(withDuration: 1){
// self.targetViewController?.view.transform = .init(scaleX: 0.5, y: 0.5);
//};
};

private func notifyOnModalWillHide(){
// wip
//UIView.animate(withDuration: 1){
// self.targetViewController?.view.transform = .identity;
//};
};

private func notifyOnModalDidHide(){
Expand Down Expand Up @@ -1558,16 +1567,6 @@ class AdaptiveModalManager: NSObject {
let coord = point[keyPath: self.modalConfig.inputValueKeyForPoint];
let closestSnapPoint = self.getClosestSnapPoint(forCoord: coord);

print(
"snapToClosestSnapPoint"
+ "\n - coord: \(coord)"
+ "\n - closestSnapPoint.interpolationIndex: \(closestSnapPoint.interpolationIndex)"
+ "\n - closestSnapPoint.snapDistance: \(closestSnapPoint.snapDistance)"
+ "\n - closestSnapPoint.interpolationPoint: \(closestSnapPoint.interpolationPoint)"
+ "\n - closestSnapPoint.snapPointConfig: \(closestSnapPoint.snapPointConfig)"
+ "\n"
);

let nextInterpolationIndex =
self.adjustInterpolationIndex(for: closestSnapPoint.interpolationIndex);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,10 @@ class AdaptiveModalPresentationController: UIPresentationController {

override func presentationTransitionDidEnd(_ completed: Bool) {
};

override func viewWillTransition(
to size: CGSize,
with coordinator: UIViewControllerTransitionCoordinator
) {
}
};
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ extension AdaptiveModalSnapPointPreset {
return self.init(layoutPreset: layoutPreset);
};

static func getDefaultInitialSnapPoint(
static func getDefaultUnderShootSnapPoint(
forDirection direction: AdaptiveModalConfig.Direction
) -> Self {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -176,8 +176,16 @@ class AdaptiveModalUtilities {
};

static func invertPercent(_ percent: CGFloat) -> CGFloat {
let offset = percent > 1 ? abs(percent - 1) : 0;
return 1 - percent + offset;
if percent >= 0 && percent <= 1 {
return 1 - percent;
};

if percent < 0 {
return abs(percent) + 1;
};

// percent > 1
return -(percent - 1);
};

static func unwrapAndSetProperty<O: AnyObject, T>(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ enum AdaptiveModalConfigTestPresets: CaseIterable {
case demo05;
case demo06;
case demo07;
case demo08;

var config: AdaptiveModalConfig {
switch self {
Expand Down Expand Up @@ -890,7 +891,7 @@ enum AdaptiveModalConfigTestPresets: CaseIterable {
modalCornerRadius: 15,
modalBackgroundOpacity: 0.85,
modalBackgroundVisualEffectIntensity: 0.9,
backgroundColor: .black,
backgroundColor: .white,
backgroundOpacity: 0.15,
backgroundVisualEffectIntensity: 0.05
)
Expand All @@ -901,8 +902,8 @@ enum AdaptiveModalConfigTestPresets: CaseIterable {
snapPoint: RNILayout(
horizontalAlignment: .center,
verticalAlignment: .center,
width: .percent(percentValue: 0.9),
height: .percent(percentValue: 0.85)
width: .stretch,
height: .stretch
),
animationKeyframe: AdaptiveModalAnimationConfig(
modalShadowOffset: .zero,
Expand All @@ -912,7 +913,7 @@ enum AdaptiveModalConfigTestPresets: CaseIterable {
modalBackgroundVisualEffectOpacity: 0,
modalBackgroundVisualEffectIntensity: 0,
backgroundColor: .white,
backgroundOpacity: 0.5,
backgroundOpacity: 0.75,
backgroundVisualEffectIntensity: 1
)
),
Expand All @@ -932,7 +933,38 @@ enum AdaptiveModalConfigTestPresets: CaseIterable {
)
),
overshootSnapPoint: AdaptiveModalSnapPointPreset(
layoutPreset: .edgeRight
layoutPreset: .offscreenRight
)
);

case .demo08: return AdaptiveModalConfig(
snapPoints: [
// Snap Point 1
AdaptiveModalSnapPointConfig(
snapPoint: RNILayout(
horizontalAlignment: .center,
verticalAlignment: .bottom,
width: .stretch,
height: .percent(percentValue: 0.3)
),
animationKeyframe: AdaptiveModalAnimationConfig(
modalShadowOffset: .init(width: 0, height: -2),
modalShadowOpacity: 0.2,
modalShadowRadius: 7,
modalCornerRadius: 25,
modalMaskedCorners: [
.layerMinXMinYCorner,
.layerMaxXMinYCorner
],
modalBackgroundOpacity: 0.9,
modalBackgroundVisualEffect: UIBlurEffect(style: .systemUltraThinMaterial),
modalBackgroundVisualEffectIntensity: 1
)
)
],
snapDirection: .bottomToTop,
overshootSnapPoint: AdaptiveModalSnapPointPreset(
layoutPreset: .fitScreen
)
);
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,8 @@ class AdaptiveModalPresentationTestViewController : UIViewController {

var currentModalManagerAdjustmentBlock: () -> Void {
let defaultBlock = {
self.adaptiveModalManager.enableOverShooting = true;

self.adaptiveModalManager.shouldSnapToUnderShootSnapPoint = true;
self.adaptiveModalManager.shouldSnapToOvershootSnapPoint = false;

Expand All @@ -122,25 +124,13 @@ class AdaptiveModalPresentationTestViewController : UIViewController {
};

switch self.currentModalConfigPreset {
case .demo01: return {
defaultBlock();
};

case .demo02: return {
defaultBlock();
};

case .demo03: return {
defaultBlock();
};

case .demo04: return {
self.adaptiveModalManager.shouldSnapToOvershootSnapPoint = true;
self.adaptiveModalManager.shouldDismissModalOnSnapToOverShootSnapPoint = true;
};

case .demo05: return {
defaultBlock();
case .demo07: return {
self.adaptiveModalManager.enableOverShooting = false;
};

default: return defaultBlock;
Expand Down

0 comments on commit a06f80b

Please sign in to comment.