-
-
Notifications
You must be signed in to change notification settings - Fork 3.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add support for mixed isHold
/ !isHold
keyframes
#1644
Conversation
Supports Core Animation engine |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🎉
{ | ||
guard !keyframes.isEmpty else { return nil } | ||
|
||
// If there is exactly one keyframe value, we can improve performance | ||
// by applying that value directly to the layer instead of creating | ||
// a relatively expensive `CAKeyframeAnimation`. | ||
if keyframes.count == 1 { | ||
let keyframeValue = try keyframeValueMapping(keyframes[0].value) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I factored this out into a separate method
/// Creates an animation that applies a single keyframe to this layer property | ||
/// - In many cases this animation can be omitted entirely, and the underlying | ||
/// property can be set directly. In that case, no animation will be created. | ||
private func singleKeyframeAnimation<ValueRepresentation>( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
|
||
/// Creates a `CAAnimationGroup` that wraps a `CAKeyframeAnimation` for each | ||
/// of the given `animationSegments` | ||
private func animationGroup<KeyframeValue, ValueRepresentation>( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is new:
df94b37
to
930a1cd
Compare
|
||
/// We can't do `extension Array where Element == Keyframe` since we don't have a way | ||
/// to specify the generic type of the keyframe itself. That would require a syntax | ||
/// like `extension <T> Array where Element == Keyframe<T>`. Instead we can use |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
generic extensions when 🤪
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
remember in like Swift 3 or earlier when you had to do this any time you wanted to extend an array with a specific Element
(since there wasn't an Element == Foo
syntax yet)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh man, those were the days
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I assume this doesn't work as the following? Or are you trying to avoid a function and have this be a computed property that doesn't support where clauses:
extension Array {
func splitByCalculationModeSegment<Value>()
-> [[Keyframe<Value>]]
where
Element == Keyframe<Value>
{
…
}
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ooooohhh good idea, let me try that
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
much better, thanks for the clever suggestion! 3f14b41
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice, LGTM!
|
||
/// We can't do `extension Array where Element == Keyframe` since we don't have a way | ||
/// to specify the generic type of the keyframe itself. That would require a syntax | ||
/// like `extension <T> Array where Element == Keyframe<T>`. Instead we can use |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh man, those were the days
|
||
/// We can't do `extension Array where Element == Keyframe` since we don't have a way | ||
/// to specify the generic type of the keyframe itself. That would require a syntax | ||
/// like `extension <T> Array where Element == Keyframe<T>`. Instead we can use |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I assume this doesn't work as the following? Or are you trying to avoid a function and have this be a computed property that doesn't support where clauses:
extension Array {
func splitByCalculationModeSegment<Value>()
-> [[Keyframe<Value>]]
where
Element == Keyframe<Value>
{
…
}
}
This PR add support for mixed
isHold
/!isHold
keyframes. Fixes #1632.isHold
corresponds toCAAnimationCalculationMode.discrete
and!isHold
corresponds to.linear
. An individualCAKeyframeAnimation
can only have a singleCAAnimationCalculationMode
, so previously the Core Animation engine only supported sets of keyframes that all used the same mode.Now, we create a separate
CAKeyframeAnimation
for each segment of keyframes with the samecalculationMode
, and then combine them into a singleCAAnimationGroup
.