diff --git a/src/private/CABasicAnimation+MotionAnimator.m b/src/private/CABasicAnimation+MotionAnimator.m index 0eacf9b..d4e808e 100644 --- a/src/private/CABasicAnimation+MotionAnimator.m +++ b/src/private/CABasicAnimation+MotionAnimator.m @@ -51,13 +51,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; } @@ -229,4 +224,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; + } + } } 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,