iOS 开发每天分享优质文章

iOS动画- (基础动画, 关键帧动画, 动画组)

2016-06-20  本文已影响2494人  广锅锅

额...... 简书居然没有复制富文本的功能, 我在有道上记的笔记, 拷到这里就纯文本了。。。
不过还好,后来花了些时间,重新使用markdown排了下版
先附上我参考的博客
http://www.cnblogs.com/kenshincui/p/3972100.html#overviewiOS开发系列--让你的应用“动”起来 - KenshinCui - 博客园
上面写得很详细, 很多概念, 分析, 我只关心实现代码, 因为我记性差, 只够记代码.

基础动画

//1.创建动画并指定动画属性
    CABasicAnimation *basicAnimation = 
[CABasicAnimation animationWithKeyPath:@"transform.rotation.z"];
     //@“transform.rotation.z” 以z轴旋转(x, y类似)
     //@“transform.rotation.z” 以z轴旋转
     //@“position” 移动动画
     
     // 2. 设置动画属性初始值, 结束值
     // basicAnimation.fromValue=[NSNumber numberWithInt:M_PI_2];
     basicAnimation.toValue = [NSNumber numberWithFloat:M_PI * 2];
     //初始值一般不需要设置
     //当是旋转动画时, toValue为结束时的角度
     //当是移动动画时, toValue为结束时的位置CGPoint
     basicAnimation.toValue = [NSValue valueWithCGPoint:location];
     
     // 设置其他动画属性
     basicAnimation.duration = 5.0; // 动画时间
     // basicAnimation.autoreverses = true;//旋转后再旋转到原来的位置
     // basicAnimation.repeatCount = HUGE_VALF; //设置重复次数,HUGE_VALF可看做无穷大,起到循环动画的效果
    
     // 4. 添加动画到图层
     [_layer addAnimation:basicAnimation forKey:@"KCBasicAnimation_Rotation"];

=========简洁版, 需要用时, 直接过来copy, paste, 我不懂得

CABasicAnimation *basicAnimation = 
[CABasicAnimation animationWithKeyPath:@"transform.rotation.z"];
basicAnimation.toValue = [NSNumber numberWithFloat:M_PI * 2];
basicAnimation.duration = 5.0;
basicAnimation.repeatCount = HUGE_VALF;
[_layer addAnimation:basicAnimation forKey:@"KCBasicAnimation_Rotation”];

关键帧动画

    // 1. 创建关键帧动画并设置动画属性
    CAKeyframeAnimation *keyframeAnimation = 
[CAKeyframeAnimation animationWithKeyPath:@"position"];
#if 0
    // 直线关键帧
    // 2. 设置关键帧, 这里有4个关键帧
    NSValue *key1 = [NSValue valueWithCGPoint:_layer.position]; // 关键帧动画不能省略初始值
    NSValue *key2 = [NSValue valueWithCGPoint:CGPointMake(250, 300)];
    NSValue *key3 = [NSValue valueWithCGPoint:CGPointMake(200, 400)];
    NSValue *key4 = [NSValue valueWithCGPoint:CGPointMake(300, 490)];
    NSArray *values = @[key1, key2, key3, key4];
    keyframeAnimation.values = values;
    
#else
    // 贝塞尔曲线关键帧
    // 2. 设置路径, 绘制贝塞尔曲线
    CGMutablePathRef path = CGPathCreateMutable();
    CGPathMoveToPoint(path, NULL, 200, 200); // 起始点
    CGPathAddCurveToPoint(path, NULL, 100, 300, 300, 500, 200, 600);
    // CGPathAddCurveToPoint(path, NULL, 控制点1.x, 控制点1.y, 控制点2.x, 控制点2.y, 终点.x, 终点.y);
    // 设置path属性
    keyframeAnimation.path = path;
    CGPathRelease(path);
    
#endif
    // 设置其他属性
    keyframeAnimation.duration = 4;
    keyframeAnimation.beginTime = CACurrentMediaTime() + 1; // 设置延迟2秒执行, 不设置这个属性, 默认直接执行
    // 3. 添加动画到图层, 会自动执行
    [_layer addAnimation:keyframeAnimation forKey:@"GGKeyframeAnimation"];

=========简洁版

    CAKeyframeAnimation *keyframeAnimation = 
[CAKeyframeAnimation animationWithKeyPath:@"position"];
#if 0
    // 直线关键帧
    NSValue *key1 = [NSValue valueWithCGPoint:_layer.position];
    NSValue *key2 = [NSValue valueWithCGPoint:CGPointMake(250, 300)];
    NSValue *key3 = [NSValue valueWithCGPoint:CGPointMake(200, 400)];
    NSValue *key4 = [NSValue valueWithCGPoint:CGPointMake(300, 490)];
    NSArray *values = @[key1, key2, key3, key4];
    keyframeAnimation.values = values;

#else
    // 贝塞尔曲线关键帧
    CGMutablePathRef path = CGPathCreateMutable();
    CGPathMoveToPoint(path, NULL, 200, 200);
    CGPathAddCurveToPoint(path, NULL, 100, 300, 300, 500, 200, 600);
    keyframeAnimation.path = path;
    CGPathRelease(path);
    
#endif
    keyframeAnimation.duration = 4;
    keyframeAnimation.beginTime = CACurrentMediaTime() + 1;
    [_layer addAnimation:keyframeAnimation forKey:@"GGKeyframeAnimation"];

动画组

#pragma mark -----------基础旋转动画-----------
- (CABasicAnimation *)rotationAnimation {
    CABasicAnimation *basicAnimation = 
[CABasicAnimation animationWithKeyPath:@"transform.rotation.z"];
    NSNumber *toValue = [NSNumber numberWithDouble:M_PI*2/3];
    basicAnimation.toValue = toValue;
    basicAnimation.repeatCount = HUGE_VALF;
    basicAnimation.removedOnCompletion = NO;
    //[basicAnimation setValue:toValue forKey:@"GGBasicAnimationRotation_ToValue”]; // 这里保存终止状态在后面会有用
    return basicAnimation;
}

#pragma mark -----------关键帧移动动画-----------
- (CAKeyframeAnimation *)translationAnimation {
    CAKeyframeAnimation *keyframeAnimation = 
[CAKeyframeAnimation animationWithKeyPath:@"position"];
    CGPoint endPoint = CGPointMake(200, 600);
    CGMutablePathRef path = CGPathCreateMutable();
    CGPathMoveToPoint(path, NULL, _layer.position.x, _layer.position.y);
    CGPathAddCurveToPoint(path, NULL, 100, 300, 300, 500, endPoint.x, endPoint.y);
    keyframeAnimation.path = path;
    CGPathRelease(path);
    //[keyframeAnimation setValue:[NSValue valueWithCGPoint:endPoint] forKey:@"GGKeyframeAnimation_endPoint"];
    return keyframeAnimation;
}

#pragma mark -----------动画组-----------
// 1. 创建动画组
CAAnimationGroup *animationGroup = [CAAnimationGroup animation];

// 2. 设置动画组中的动画和其他属性
CABasicAnimation *baseAnimation = [self rotationAnimation]; // 创建单个动画时, 只需要设置好初始值,结束值
CAKeyframeAnimation *keyframeAnimation = [self translationAnimation]; // 只需要设置好关键帧,或画好运动路径
// 可以在动画组里添加多种动画效果, 基本动画或关键帧动画都可以组合
animationGroup.animations = @[baseAnimation, keyframeAnimation];
// 其他设置可以统一使用animationGroup设置
animationGroup.duration = 2; // 设置动画时间, 如果动画组中动画已经设置过则动画属性不再生效
//    animationGroup.beginTime = CACurrentMediaTime()+1;

// 3. 给图层添加动画
[_layer addAnimation:animationGroup forKey:nil];

动画结束后, 状态(位置, 旋转角度)会复原
图层动画的本质就是将图层内部的内容转化为位图经硬件操作形成一种动画效果,其实图层本身并没有任何的变化。
解决办法: 设置动画的代理, 实现 - (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag
当动画结束时, 把动画的状态设置为动画停止时的状态

CABasicAnimation, CAKeyframeAnimation, CAAnimationGroup 都可以设置代理, 实现代理方法

// e.g 对上述动画组实现的动画实现状态修改
- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag {
    CAAnimationGroup *animationGroup = (CAAnimationGroup *)anim;
    CABasicAnimation *basicAnimation = animationGroup.animations[0];
    CAKeyframeAnimation *keyframeAnimation = animationGroup.animations[1];
    
    // 通过在前面设置的key名, 获取到停止状态的值
    NSNumber *toValue = [basicAnimation valueForKey:@"GGBasicAnimationRotation_ToValue"];
    CGPoint endPoint  = [[keyframeAnimation valueForKey:@"GGKeyframeAnimation_endPoint"] CGPointValue];
    [CATransaction begin];
    [CATransaction setDisableActions:YES];

    // 设置视图的属性为停止状态的值
    _layer.position = endPoint;
    _layer.transform = CATransform3DMakeRotation([toValue doubleValue], 0, 0, 1);
    [CATransaction commit];
}

// 由于图层具有动画效果, 直接设置属性, 会导致隐式动画出现, 为了取消隐式动画, 需要将设置属性的代码写在. . . .位置
[CATransaction begin];
[CATransaction setDisableActions:YES];
. . . . . .
[CATransaction commit];

上一篇下一篇

猜你喜欢

热点阅读