Animation
ComponentKit exposes three ways to perform animations on a component.
animationsOnInitialMount
Override this method to specify how to animate the initial appearance of a component. For example, if you were implementing a component that indicates network reachability issues, you could fade in the component:
- (std::vector<CKComponentAnimation>)animationsOnInitialMount
{
return { {self, fadeToAppear()} };
}
static CAAnimation *fadeToAppear()
{
CABasicAnimation *fade = [CABasicAnimation animationWithKeyPath:@"opacity"];
fade.fromValue = @(0);
fade.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut];
fade.duration = 0.5;
return fade;
}
animationsFromPreviousComponent:
Override this method to specify how to animate between two versions of a component. Here’s an example from the example app:
- (std::vector<CKComponentAnimation>)animationsFromPreviousComponent:(InteractiveQuoteComponent *)previousComponent
{
if (previousComponent->_overlay == nil && _overlay != nil) {
return { {_overlay, scaleToAppear()} }; // Scale the overlay in when it appears.
} else {
return {};
}
}
static CAAnimation *scaleToAppear()
{
CABasicAnimation *scale = [CABasicAnimation animationWithKeyPath:@"transform"];
scale.fromValue = [NSValue valueWithCATransform3D:CATransform3DMakeScale(0.0, 0.0, 0.0)];
scale.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut];
scale.duration = 0.2;
return scale;
}
boundsAnimationFromPreviousComponent:
Override this method to specify how the top-level bounds of a component should animate inside a UICollectionView
. For example, if you were implementing an expandable article component that changes its height, you could specify a spring animation for changing the cell bounds:
- (CKComponentBoundsAnimation)boundsAnimationFromPreviousComponent:(ArticleComponent *)previousComponent
{
if (previousComponent->_state == ArticleComponentStateCollapsed && _state == ArticleComponentStateExpanded) {
return {
.mode = CKComponentBoundsAnimationModeSpring,
.duration = 0.5,
.springDampingRatio = 0.7,
.springInitialVelocity = 1.0,
};
} else {
return {};
}
}
Notes
If you implement either method, your component must have a scope.
If updating your component’s state changes it’s bounds, both boundsAnimationFromPreviousComponent
and animationsFromPreviousComponent
will be called.