创建自定义动画: KYSpringLayerAnimation
- 创建CAKeyframeAnimation,自定义keypath
- 根据values变化曲线和动画持续时间,补齐1s60帧值变化数组
@interface KYSpringLayerAnimation : NSObject
// 自定义KeyPath,根据传入的值变换、持续时间,计算出每一帧值得变换,返回到values
// 1s = 60帧, 0.3s动画 = 0.3 * 60 = 18帧
{
NSInteger numOfFrames = duration * 60;
// 开辟一个容纳 18帧数据的数组,避免空间浪费
NSMutableArray *values = [NSMutableArray arrayWithCapacity:numOfFrames];
for (NSInteger i = 0; i < numOfFrames; i++) {
[values addObject:@(0.0)];
}
CGFloat diff = [toValue floatValue] - [fromValue floatValue];
for (NSInteger frame = 0; frame<numOfFrames; frame++) {
CGFloat x = (CGFloat)frame / (CGFloat)numOfFrames;
// 值的变化曲线为一条直线
CGFloat value = [fromValue floatValue] + diff * x;
values[frame] = @(value);
}
return values;
}
执行动画的视图 : UIView
- 将自定义Layer与视图绑定
- 响应点击触发动画
- 实现代理CAAnimationDelegate,做动画的衔接播放
-(void)willMoveToSuperview:(UIView *)newSuperview{
_menuLayer = [MenuLayer layer];
_menuLayer.frame = self.bounds;
_menuLayer.contentsScale = [UIScreen mainScreen].scale;
[self.layer addSublayer:_menuLayer];
[_menuLayer setNeedsDisplay];
}
-(void)touchBegan{
[self.menuLayer addAnimation:openAnimation_1 forKey:@"openAnimation_1"];
}
-(void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag{
if (flag) {
if ([anim isEqual:[self.menuLayer animationForKey:@"openAnimation_1"]]) {
[self.menuLayer removeAllAnimations];
[self.menuLayer addAnimation:[_animationQueue objectAtIndex:1] forKey:@"openAnimation_2"];
_menuLayer.animState = STATE2;
}else if ([anim isEqual:[self.menuLayer animationForKey:@"openAnimation_2"]]) {
[self.menuLayer removeAllAnimations];
[self.menuLayer addAnimation:[_animationQueue objectAtIndex:2] forKey:@"openAnimation_3"];
_menuLayer.animState = STATE3;
}else if ([anim isEqual:[self.menuLayer animationForKey:@"openAnimation_3"]]) {
self.menuLayer.xAxisPercent = 1.0;
[self.menuLayer removeAllAnimations];
self.userInteractionEnabled = YES;
}
}
}
对应视图的Layer
- 重写 drawInContext:(CGContextRef)ctx 实现动画效果
@interface MenuLayer : CALayer
// 初始化
-(id)initWithLayer:(MenuLayer *)layer{
self = [super initWithLayer:layer];
if (self) {
//...在这里拷贝layer 的所有 property
self.showDebug = layer.showDebug;
self.xAxisPercent = layer.xAxisPercent;
self.animState = layer.animState;
}
return self;
}
+(BOOL)needsDisplayForKey:(NSString *)key{
if ([key isEqualToString:@"xAxisPercent"]) {
return YES;
}
return [super needsDisplayForKey:key];
}
网友评论