Skip to content
This repository has been archived by the owner on Aug 30, 2023. It is now read-only.

Spring animations now take velocity into account when determining duration. #56

Merged
merged 4 commits into from
Nov 22, 2017
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 14 additions & 6 deletions src/private/CABasicAnimation+MotionAnimator.m
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down Expand Up @@ -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;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is referencing the class before it was introduced OK? I believe CASpringAnimation was introduced in iOS 9?
https://developer.apple.com/documentation/quartzcore/caspringanimation

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not strictly an encouraged behavior, no. But this allows us to expand our min SDK support to iOS 8. Is a trade-off, but a relatively safe one.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok. As long as it doesn't crash with undefined symbols (or generate compiler errors). Sounds good to me.

#pragma clang diagnostic pop

// This API is only available on iOS 9+
if ([springAnimation respondsToSelector:@selector(settlingDuration)]) {
animation.duration = springAnimation.settlingDuration;
}
}
}
13 changes: 13 additions & 0 deletions tests/unit/InitialVelocityTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down