From 8c3a2ea8913e1a659531ba28fb6e04796e40dcc2 Mon Sep 17 00:00:00 2001 From: Dominic Go <18517029+dominicstop@users.noreply.github.com> Date: Sat, 17 Jun 2023 01:57:38 +0800 Subject: [PATCH] =?UTF-8?q?=F0=9F=92=AB=20Update:=20Exp=20-=20`AdaptiveMod?= =?UTF-8?q?al`?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Summary: Update experiment/test - `swift-programmatic-modal/AdaptiveModal`. --- .../AdaptiveModal/AdaptiveModalConfig.swift | 28 ++--------- .../AdaptiveModal/AdaptiveModalManager.swift | 45 +++++++++++++++-- .../AdaptiveModalSnapPoint.swift | 48 +++++++++++++------ .../AdaptiveModalSnapPointPreset.swift | 14 +++--- .../RNILayout/RNILayout.swift | 10 ++-- .../RNILayout/RNILayoutPreset.swift | 22 ++++++--- .../Test/AdaptiveModalConfigTestPresets.swift | 4 +- ...eModalPresentationTestViewController.swift | 2 +- 8 files changed, 109 insertions(+), 64 deletions(-) diff --git a/experiments/swift-programmatic-modal/AdaptiveModal/AdaptiveModalConfig.swift b/experiments/swift-programmatic-modal/AdaptiveModal/AdaptiveModalConfig.swift index c1d29774..29a54b49 100644 --- a/experiments/swift-programmatic-modal/AdaptiveModal/AdaptiveModalConfig.swift +++ b/experiments/swift-programmatic-modal/AdaptiveModal/AdaptiveModalConfig.swift @@ -43,29 +43,11 @@ struct AdaptiveModalConfig { // let snapSwipeVelocityThreshold: CGFloat = 0; var snapPoints: [AdaptiveModalSnapPointConfig] { - var items: [AdaptiveModalSnapPointConfig] = []; - - if let snapPointFirst = self.baseSnapPoints.first { - let initialSnapPointConfig = AdaptiveModalSnapPointConfig( - fromSnapPointPreset: self.undershootSnapPoint, - fromBaseLayoutConfig: snapPointFirst.snapPoint - ); - - items.append(initialSnapPointConfig); - }; - - items += self.baseSnapPoints; - - if let snapPointLast = self.baseSnapPoints.last { - let overshootSnapPointConfig = AdaptiveModalSnapPointConfig( - fromSnapPointPreset: self.overshootSnapPoint, - fromBaseLayoutConfig: snapPointLast.snapPoint - ); - - items.append(overshootSnapPointConfig); - }; - - return items; + .Element.deriveSnapPoints( + undershootSnapPoint: self.undershootSnapPoint, + inBetweenSnapPoints: self.baseSnapPoints, + overshootSnapPoint: self.overshootSnapPoint + ); }; var snapPointLastIndex: Int { diff --git a/experiments/swift-programmatic-modal/AdaptiveModal/AdaptiveModalManager.swift b/experiments/swift-programmatic-modal/AdaptiveModal/AdaptiveModalManager.swift index 5ac0ed9d..5634d1f4 100644 --- a/experiments/swift-programmatic-modal/AdaptiveModal/AdaptiveModalManager.swift +++ b/experiments/swift-programmatic-modal/AdaptiveModal/AdaptiveModalManager.swift @@ -122,6 +122,11 @@ class AdaptiveModalManager: NSObject { return displayLinkStartTimestamp + animator.duration; }; + private var rangeAnimators: [AdaptiveModalRangePropertyAnimator?] {[ + self.backgroundVisualEffectAnimator, + self.modalBackgroundVisualEffectAnimator + ]}; + // MARK: - Properties - Gesture-Related // ------------------------------------- @@ -910,7 +915,7 @@ class AdaptiveModalManager: NSObject { self.didTriggerSetup = false; }; - + private func cleanup() { self.clearGestureValues(); self.clearAnimators(); @@ -1320,12 +1325,13 @@ class AdaptiveModalManager: NSObject { func snapTo( interpolationIndex nextIndex: Int, + interpolationPoint: AdaptiveModalInterpolationPoint? = nil, completion: (() -> Void)? = nil ) { self.nextInterpolationIndex = nextIndex; - let nextInterpolationPoint = - self.interpolationSteps[nextIndex]; + let nextInterpolationPoint = interpolationPoint + ?? self.interpolationSteps[nextIndex]; self.notifyOnModalWillSnap(); @@ -1395,8 +1401,37 @@ class AdaptiveModalManager: NSObject { self.snapTo(interpolationIndex: nextIndex, completion: completion); }; - func dismissModal(completion: (() -> Void)? = nil){ + func dismissModal( + useInBetweenSnapPoints: Bool = false, + completion: (() -> Void)? = nil + ){ + let nextIndex = 0; - self.snapTo(interpolationIndex: nextIndex, completion: completion); + + if useInBetweenSnapPoints { + self.snapTo(interpolationIndex: nextIndex, completion: completion); + + } else { + let currentSnapPointConfig = self.currentSnapPointConfig; + + let undershootSnapPointConfig = AdaptiveModalSnapPointConfig( + fromSnapPointPreset: self.modalConfig.undershootSnapPoint, + fromBaseLayoutConfig: currentSnapPointConfig.snapPoint + ); + + let undershootInterpolationPoint = AdaptiveModalInterpolationPoint( + usingModalConfig: self.modalConfig, + snapPointIndex: nextIndex, + layoutValueContext: self.layoutValueContext, + snapPointConfig: undershootSnapPointConfig, + prevInterpolationPoint: self.currentInterpolationStep + ); + + self.snapTo( + interpolationIndex: nextIndex, + interpolationPoint: undershootInterpolationPoint, + completion: completion + ); + }; }; }; diff --git a/experiments/swift-programmatic-modal/AdaptiveModal/AdaptiveModalSnapPoint.swift b/experiments/swift-programmatic-modal/AdaptiveModal/AdaptiveModalSnapPoint.swift index 2d6bf641..aeb59b55 100644 --- a/experiments/swift-programmatic-modal/AdaptiveModal/AdaptiveModalSnapPoint.swift +++ b/experiments/swift-programmatic-modal/AdaptiveModal/AdaptiveModalSnapPoint.swift @@ -23,7 +23,7 @@ struct AdaptiveModalSnapPointConfig { fromSnapPointPreset snapPointPreset: AdaptiveModalSnapPointPreset, fromBaseLayoutConfig baseLayoutConfig: RNILayout ) { - let snapPointLayoutPreset = snapPointPreset.snapPointPreset; + let snapPointLayoutPreset = snapPointPreset.layoutPreset; let snapPointLayout = snapPointLayoutPreset.getLayoutConfig( fromBaseLayoutConfig: baseLayoutConfig @@ -34,16 +34,36 @@ struct AdaptiveModalSnapPointConfig { }; }; -//extension AdaptiveModalSnapPointConfig { -// -// static func deriveSnapPoints( -// initialSnapPoint: AdaptiveModalSnapPointPreset, -// inBetweenSnapPoints: [AdaptiveModalSnapPointConfig], -// overshootSnapPoint: AdaptiveModalSnapPointPreset -// ) -> [AdaptiveModalSnapPointConfig] { -// -// var snapPoints: [AdaptiveModalSnapPointConfig] = []; -// -// return snapPoints; -// }; -//}; +extension AdaptiveModalSnapPointConfig { + + static func deriveSnapPoints( + undershootSnapPoint: AdaptiveModalSnapPointPreset, + inBetweenSnapPoints: [AdaptiveModalSnapPointConfig], + overshootSnapPoint: AdaptiveModalSnapPointPreset + ) -> [AdaptiveModalSnapPointConfig] { + + var items: [AdaptiveModalSnapPointConfig] = []; + + if let snapPointFirst = inBetweenSnapPoints.first { + let initialSnapPointConfig = AdaptiveModalSnapPointConfig( + fromSnapPointPreset: undershootSnapPoint, + fromBaseLayoutConfig: snapPointFirst.snapPoint + ); + + items.append(initialSnapPointConfig); + }; + + items += inBetweenSnapPoints; + + if let snapPointLast = inBetweenSnapPoints.last { + let overshootSnapPointConfig = AdaptiveModalSnapPointConfig( + fromSnapPointPreset: overshootSnapPoint, + fromBaseLayoutConfig: snapPointLast.snapPoint + ); + + items.append(overshootSnapPointConfig); + }; + + return items; + }; +}; diff --git a/experiments/swift-programmatic-modal/AdaptiveModal/AdaptiveModalSnapPointPreset.swift b/experiments/swift-programmatic-modal/AdaptiveModal/AdaptiveModalSnapPointPreset.swift index 612089d1..eee8389d 100644 --- a/experiments/swift-programmatic-modal/AdaptiveModal/AdaptiveModalSnapPointPreset.swift +++ b/experiments/swift-programmatic-modal/AdaptiveModal/AdaptiveModalSnapPointPreset.swift @@ -9,14 +9,14 @@ import Foundation struct AdaptiveModalSnapPointPreset { - let snapPointPreset: RNILayoutPreset; + let layoutPreset: RNILayoutPreset; let animationKeyframe: AdaptiveModalAnimationConfig?; init( - snapPoint: RNILayoutPreset, + layoutPreset: RNILayoutPreset, animationKeyframe: AdaptiveModalAnimationConfig? = nil ) { - self.snapPointPreset = snapPoint; + self.layoutPreset = layoutPreset; self.animationKeyframe = animationKeyframe; }; }; @@ -26,7 +26,7 @@ extension AdaptiveModalSnapPointPreset { forDirection direction: AdaptiveModalConfig.Direction ) -> Self { - let snapPoint: RNILayoutPreset = { + let layoutPreset: RNILayoutPreset = { switch direction { case .bottomToTop: return .edgeTop; case .topToBottom: return .edgeBottom; @@ -35,14 +35,14 @@ extension AdaptiveModalSnapPointPreset { }; }(); - return self.init(snapPoint: snapPoint); + return self.init(layoutPreset: layoutPreset); }; static func getDefaultInitialSnapPoint( forDirection direction: AdaptiveModalConfig.Direction ) -> Self { - let snapPoint: RNILayoutPreset = { + let layoutPreset: RNILayoutPreset = { switch direction { case .bottomToTop: return .offscreenBottom; case .topToBottom: return .offscreenTop; @@ -51,6 +51,6 @@ extension AdaptiveModalSnapPointPreset { }; }(); - return self.init(snapPoint: snapPoint); + return self.init(layoutPreset: layoutPreset); }; }; diff --git a/experiments/swift-programmatic-modal/RNILayout/RNILayout.swift b/experiments/swift-programmatic-modal/RNILayout/RNILayout.swift index 82c0f026..a7532a24 100644 --- a/experiments/swift-programmatic-modal/RNILayout/RNILayout.swift +++ b/experiments/swift-programmatic-modal/RNILayout/RNILayout.swift @@ -149,7 +149,7 @@ public struct RNILayout { rect.setPoint(minY: context.targetRect.minY); case .bottom: - rect.setPoint(maxY: context.targetRect.maxY); + rect.origin.y = context.targetRect.height - rect.height; }; }; @@ -205,7 +205,7 @@ public struct RNILayout { let computedMarginHorizontal = (computedMarginLeft ?? 0) + (computedMarginRight ?? 0); - let computedMargiVertical = + let computedMarginVertical = (computedMarginTop ?? 0) + (computedMarginBottom ?? 0); // Margin - X-Axis @@ -238,14 +238,14 @@ public struct RNILayout { let shouldRecomputeXAxis: Bool = { switch self.width.mode { - case .stretch: return true; + case .stretch: return abs(computedMarginHorizontal) < rect.width; default: return false; }; }(); let shouldRecomputeYAxis: Bool = { switch self.height.mode { - case .stretch: return true; + case .stretch: return abs(computedMarginVertical) < rect.height; default: return false; }; }(); @@ -255,7 +255,7 @@ public struct RNILayout { }; if shouldRecomputeYAxis { - rect.size.height = rect.size.height - computedMargiVertical; + rect.size.height = rect.size.height - computedMarginVertical; }; if shouldRecomputeXAxis || shouldRecomputeYAxis { diff --git a/experiments/swift-programmatic-modal/RNILayout/RNILayoutPreset.swift b/experiments/swift-programmatic-modal/RNILayout/RNILayoutPreset.swift index 71453312..ef68098b 100644 --- a/experiments/swift-programmatic-modal/RNILayout/RNILayoutPreset.swift +++ b/experiments/swift-programmatic-modal/RNILayout/RNILayoutPreset.swift @@ -43,6 +43,7 @@ enum RNILayoutPreset { return .init( derivedFrom: baseLayoutConfig, verticalAlignment: .bottom, + marginTop: .constant(0), marginBottom: .percent( relativeTo: .currentHeight, percentValue: -1 @@ -56,7 +57,8 @@ enum RNILayoutPreset { marginTop: .percent( relativeTo: .currentHeight, percentValue: -1 - ) + ), + marginBottom: .constant(0) ); case .offscreenLeft: @@ -66,13 +68,15 @@ enum RNILayoutPreset { marginLeft: .percent( relativeTo: .currentWidth, percentValue: -1 - ) + ), + marginRight: .constant(0) ); case .offscreenRight: return .init( derivedFrom: baseLayoutConfig, horizontalAlignment: .right, + marginLeft: .constant(0), marginRight: .percent( relativeTo: .currentWidth, percentValue: 1 @@ -89,7 +93,8 @@ enum RNILayoutPreset { return .init( derivedFrom: baseLayoutConfig, verticalAlignment: .top, - marginTop: .percent( + marginTop: .constant(0), + marginBottom: .percent( relativeTo: .currentHeight, percentValue: 0.5 ) @@ -100,9 +105,10 @@ enum RNILayoutPreset { derivedFrom: baseLayoutConfig, verticalAlignment: .top, marginTop: .percent( - relativeTo: .currentHeight, - percentValue: -0.5 - ) + relativeTo: .currentHeight, + percentValue: -0.5 + ), + marginBottom: .constant(0) ); case .halfOffscreenLeft: @@ -112,13 +118,15 @@ enum RNILayoutPreset { marginLeft: .percent( relativeTo: .currentWidth, percentValue: -0.5 - ) + ), + marginRight: .constant(0) ); case .halfOffscreenRight: return .init( derivedFrom: baseLayoutConfig, horizontalAlignment: .right, + marginLeft: .constant(0), marginRight: .percent( relativeTo: .currentWidth, percentValue: 0.5 diff --git a/experiments/swift-programmatic-modal/Test/AdaptiveModalConfigTestPresets.swift b/experiments/swift-programmatic-modal/Test/AdaptiveModalConfigTestPresets.swift index 5f3cfd45..beaa83a4 100644 --- a/experiments/swift-programmatic-modal/Test/AdaptiveModalConfigTestPresets.swift +++ b/experiments/swift-programmatic-modal/Test/AdaptiveModalConfigTestPresets.swift @@ -85,7 +85,7 @@ enum AdaptiveModalConfigTestPresets: CaseIterable { ], snapDirection: .bottomToTop, overshootSnapPoint: AdaptiveModalSnapPointPreset( - snapPoint: .fitScreenVertically + layoutPreset: .fitScreenVertically ) ); @@ -314,7 +314,7 @@ enum AdaptiveModalConfigTestPresets: CaseIterable { shouldClampModalLastX: true ), overshootSnapPoint: AdaptiveModalSnapPointPreset( - snapPoint: .fitScreen + layoutPreset: .fitScreen ) ); }; diff --git a/experiments/swift-programmatic-modal/Test/AdaptiveModalPresentationTestViewController.swift b/experiments/swift-programmatic-modal/Test/AdaptiveModalPresentationTestViewController.swift index 08f93196..31140e02 100644 --- a/experiments/swift-programmatic-modal/Test/AdaptiveModalPresentationTestViewController.swift +++ b/experiments/swift-programmatic-modal/Test/AdaptiveModalPresentationTestViewController.swift @@ -45,7 +45,7 @@ class TestModalViewController: UIViewController, AdaptiveModalEventNotifiable { stack.axis = .vertical; stack.distribution = .equalSpacing; stack.alignment = .center; - stack.spacing = 15; + stack.spacing = 10; stack.addArrangedSubview(self.floatingViewLabel); stack.addArrangedSubview(presentButton);