From a49a9097fbb7ad1352a7d12af0a4184f8165af92 Mon Sep 17 00:00:00 2001 From: Jeff Verkoeyen Date: Tue, 21 Nov 2017 13:28:36 -0500 Subject: [PATCH 1/2] Spring animations now take velocity into account when determining duration. Prior to this change, spring animations were calculating their settling time prior to having set their initial velocity. After this change, spring animations will calculate their settling time after having set the initial velocity. --- src/private/CABasicAnimation+MotionAnimator.m | 20 +++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/src/private/CABasicAnimation+MotionAnimator.m b/src/private/CABasicAnimation+MotionAnimator.m index 61a57e5..bec6dd0 100644 --- a/src/private/CABasicAnimation+MotionAnimator.m +++ b/src/private/CABasicAnimation+MotionAnimator.m @@ -47,13 +47,8 @@ spring.mass = timing.curve.data[MDMSpringMotionCurveDataIndexMass]; spring.stiffness = timing.curve.data[MDMSpringMotionCurveDataIndexTension]; spring.damping = timing.curve.data[MDMSpringMotionCurveDataIndexFriction]; + spring.duration = timing.duration; - // This API is only available on iOS 9+ - if ([spring respondsToSelector:@selector(settlingDuration)]) { - spring.duration = spring.settlingDuration; - } else { - spring.duration = timing.duration; - } animation = spring; break; } @@ -225,4 +220,17 @@ void MDMConfigureAnimation(CABasicAnimation *animation, springAnimation.initialVelocity = absoluteInitialVelocity / displacement; } } + + // Update the animation's duration to match the proposed settling duration. +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wpartial-availability" + if ([animation isKindOfClass:[CASpringAnimation class]]) { + CASpringAnimation *springAnimation = (CASpringAnimation *)animation; +#pragma clang diagnostic pop + + // This API is only available on iOS 9+ + if ([springAnimation respondsToSelector:@selector(settlingDuration)]) { + animation.duration = springAnimation.settlingDuration; + } + } } From 7f7a49a7de644c04da96d0a6ec2c74421a75648c Mon Sep 17 00:00:00 2001 From: Jeff Verkoeyen Date: Tue, 21 Nov 2017 13:32:41 -0500 Subject: [PATCH 2/2] Add tests. --- tests/unit/InitialVelocityTests.swift | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/tests/unit/InitialVelocityTests.swift b/tests/unit/InitialVelocityTests.swift index 90af11f..06378f9 100644 --- a/tests/unit/InitialVelocityTests.swift +++ b/tests/unit/InitialVelocityTests.swift @@ -121,6 +121,19 @@ class InitialVelocityTests: XCTestCase { } } + func testVelocityInfluencesDuration() { + let velocity: CGFloat = 50 + animate(from: 0, to: 100, withVelocity: velocity) + + XCTAssertEqual(addedAnimations.count, 3) + addedAnimations.flatMap { $0 as? CASpringAnimation }.forEach { animation in + XCTAssertEqual(animation.duration, animation.settlingDuration, + "from: \(animation.fromValue!), " + + "to: \(animation.toValue!), " + + "withVelocity: \(velocity)") + } + } + private func animate(from: CGFloat, to: CGFloat, withVelocity velocity: CGFloat) { let timing = MotionTiming(delay: 0, duration: 0.7,