From 25ca9487fb9490a4ba57c65eca23229f18138e70 Mon Sep 17 00:00:00 2001 From: Shin Yamamoto Date: Mon, 30 Nov 2020 21:21:21 +0900 Subject: [PATCH] Open the default behavior class (#406) * Allow open access to FloatingPanelDefaultBehavior * Move the default presenting & dismissing animators * Add the public initializer of FloatingPanelDefaultBehavior --- Sources/Behavior.swift | 27 ++++++++------------------- Sources/Controller.swift | 21 +++++++++++++++++++++ Sources/Core.swift | 6 ++---- Sources/Transitioning.swift | 6 ++---- 4 files changed, 33 insertions(+), 27 deletions(-) diff --git a/Sources/Behavior.swift b/Sources/Behavior.swift index 0c6bc008..75a55e7a 100644 --- a/Sources/Behavior.swift +++ b/Sources/Behavior.swift @@ -48,37 +48,26 @@ public protocol FloatingPanelBehavior { /// The default behavior object for a panel /// /// This behavior object is fine-tuned to behave as a search panel(card) in Apple Maps on iPhone portrait orientation. -public class FloatingPanelDefaultBehavior: FloatingPanelBehavior { - public var springDecelerationRate: CGFloat { +open class FloatingPanelDefaultBehavior: FloatingPanelBehavior { + public init() {} + + open var springDecelerationRate: CGFloat { return UIScrollView.DecelerationRate.fast.rawValue + 0.001 } - public var springResponseTime: CGFloat { + open var springResponseTime: CGFloat { return 0.4 } - public var momentumProjectionRate: CGFloat { + open var momentumProjectionRate: CGFloat { return UIScrollView.DecelerationRate.normal.rawValue } - public func redirectionalProgress(_ fpc: FloatingPanelController, from: FloatingPanelState, to: FloatingPanelState) -> CGFloat { + open func redirectionalProgress(_ fpc: FloatingPanelController, from: FloatingPanelState, to: FloatingPanelState) -> CGFloat { return 0.5 } - func addPanelAnimator(_ fpc: FloatingPanelController, to: FloatingPanelState) -> UIViewPropertyAnimator { - return UIViewPropertyAnimator(duration: 0.0, - timingParameters: UISpringTimingParameters(decelerationRate: UIScrollView.DecelerationRate.fast.rawValue, - frequencyResponse: 0.25)) - } - - func removePanelAnimator(_ fpc: FloatingPanelController, from: FloatingPanelState, with velocity: CGVector) -> UIViewPropertyAnimator { - return UIViewPropertyAnimator(duration: 0.0, - timingParameters: UISpringTimingParameters(decelerationRate: UIScrollView.DecelerationRate.fast.rawValue, - frequencyResponse: 0.25, - initialVelocity: velocity)) - } - - public func allowsRubberBanding(for edge: UIRectEdge) -> Bool { + open func allowsRubberBanding(for edge: UIRectEdge) -> Bool { return false } } diff --git a/Sources/Controller.swift b/Sources/Controller.swift index 84069a6f..2b064fb1 100644 --- a/Sources/Controller.swift +++ b/Sources/Controller.swift @@ -649,6 +649,27 @@ extension FloatingPanelController { #endif delegate?.floatingPanelDidMove?(self) } + + func animatorForPresenting(to: FloatingPanelState) -> UIViewPropertyAnimator { + if let animator = delegate?.floatingPanel?(self, animatorForPresentingTo: to) { + return animator + } + let timingParameters = UISpringTimingParameters(decelerationRate: UIScrollView.DecelerationRate.fast.rawValue, + frequencyResponse: 0.25) + return UIViewPropertyAnimator(duration: 0.0, + timingParameters: timingParameters) + } + + func animatorForDismissing(with velocity: CGVector) -> UIViewPropertyAnimator { + if let animator = delegate?.floatingPanel?(self, animatorForDismissingWith: velocity) { + return animator + } + let timingParameters = UISpringTimingParameters(decelerationRate: UIScrollView.DecelerationRate.fast.rawValue, + frequencyResponse: 0.25, + initialVelocity: velocity) + return UIViewPropertyAnimator(duration: 0.0, + timingParameters: timingParameters) + } } extension FloatingPanelController { diff --git a/Sources/Core.swift b/Sources/Core.swift index 8dfd55c9..3572ce71 100644 --- a/Sources/Core.swift +++ b/Sources/Core.swift @@ -123,12 +123,10 @@ class Core: NSObject, UIGestureRecognizerDelegate { let animator: UIViewPropertyAnimator switch (from, to) { case (.hidden, let to): - animator = vc.delegate?.floatingPanel?(vc, animatorForPresentingTo: to) - ?? FloatingPanelDefaultBehavior().addPanelAnimator(vc, to: to) + animator = vc.animatorForPresenting(to: to) case (let from, .hidden): let animationVector = CGVector(dx: abs(removalVector.dx), dy: abs(removalVector.dy)) - animator = vc.delegate?.floatingPanel?(vc, animatorForDismissingWith: .zero) - ?? FloatingPanelDefaultBehavior().removePanelAnimator(vc, from: from, with: animationVector) + animator = vc.animatorForDismissing(with: animationVector) default: move(to: to, with: 0) { self.moveAnimator = nil diff --git a/Sources/Transitioning.swift b/Sources/Transitioning.swift index 11bbf890..a1a94dcf 100644 --- a/Sources/Transitioning.swift +++ b/Sources/Transitioning.swift @@ -86,8 +86,7 @@ class ModalPresentTransition: NSObject, UIViewControllerAnimatedTransitioning { let fpc = transitionContext?.viewController(forKey: .to) as? FloatingPanelController else { fatalError()} - let animator = fpc.delegate?.floatingPanel?(fpc, animatorForPresentingTo: fpc.layout.initialState) - ?? FloatingPanelDefaultBehavior().addPanelAnimator(fpc, to: fpc.layout.initialState) + let animator = fpc.animatorForPresenting(to: fpc.layout.initialState) return TimeInterval(animator.duration) } @@ -108,8 +107,7 @@ class ModalDismissTransition: NSObject, UIViewControllerAnimatedTransitioning { let fpc = transitionContext?.viewController(forKey: .from) as? FloatingPanelController else { fatalError()} - let animator = fpc.delegate?.floatingPanel?(fpc, animatorForDismissingWith: .zero) - ?? FloatingPanelDefaultBehavior().removePanelAnimator(fpc, from: fpc.state, with: .zero) + let animator = fpc.animatorForDismissing(with: .zero) return TimeInterval(animator.duration) }