您的位置:首页 > 其它

Core Animation 基本动画效果汇总

2015-07-13 17:04 295 查看
前几篇文章中,我详细的说明了Core Animation相关的理论知识。这一节,我将举例说明基本动画的使用。

一、 CABasicAnimation

首先我创建一个用于实现动画的图层,代码如下:

- (void)viewDidLoad {
    [super viewDidLoad];
    CALayer *layer = [CALayer layer];
    layer.position = CGPointMake(100, 100);
    layer.bounds = CGRectMake(0, 0, 100, 100);
    layer.backgroundColor = [UIColor redColor].CGColor;
    [self.view.layer addSublayer:layer];
    self.layer = layer;
}


1. 透明度变化

动画代码如下:

CABasicAnimation *fadeAnimation = [CABasicAnimation animationWithKeyPath:@"opacity"];
// 动画起始值
fadeAnimation.fromValue = @(1.0);
// 动画结束值
fadeAnimation.toValue = @(0.0);
// 动画持续时间
fadeAnimation.duration = 2.0;
// key 动画标识
[self.layer addAnimation:fadeAnimation forKey:@"opacityAnimation"];


动画效果如下:



可以看出,动画是按照设想的执行,但是在动画结束后,又返回原来的状态了。

原因分析:注意到,本例中,我使用的显式动画,不同于隐式动画,隐式动画会更新图层对象的值。而显式动画不会更改图层树中的数据。显式动画仅是创建了一个动画。在动画结束之后,Core Animation从图层中移除该动画对象并使用当前的数据值重绘图层。(所以显式动画会出现动画结束后,突然回到原始位置的情况)。

解决方案:

I. 更新赋值图层属性

这种方案的原理就是动画开始的时候,就确定图层的最终值;这样操作的话,当动画结束并且被移除后,显示的是图层树中的值。代码如下:

CABasicAnimation *fadeAnimation = [CABasicAnimation animationWithKeyPath:@"opacity"];
// 动画起始值
fadeAnimation.fromValue = @(1.0);
// 动画结束值
fadeAnimation.toValue = @(0.0);
// 动画持续时间
fadeAnimation.duration = 3.0;
/*一开始就确定动画结束后,图层最终的透明值*/
self.layer.opacity = 0;
// key 动画标识
[self.layer addAnimation:fadeAnimation forKey:@"opacityAnimation"];


II. 不移除动画,并填充

CABasicAnimation *fadeAnimation = [CABasicAnimation animationWithKeyPath:@"opacity"];
// 动画起始值
fadeAnimation.fromValue = @(1.0);
// 动画结束值
fadeAnimation.toValue = @(0.0);
// 动画持续时间
fadeAnimation.duration = 3.0;
/* 动画执行完毕后不要删除动画 */
fadeAnimation.removedOnCompletion = NO;
/* 保持最新的状态 */
fadeAnimation.fillMode = kCAFillModeForwards;
// key 动画标识
[self.layer addAnimation:fadeAnimation forKey:@"opacityAnimation"];</span>
这样操作的话,动画并没有被移除掉,而是会一直驻留在内存中,所以应该在控制器销毁的时候,应该也将动画移除掉(根据动画标识)。

- (void)dealloc {
    [self.layer removeAnimationForKey:@"opacityAnimation"];
}


有人会问,为什么不使用UIView的block操作来实现此功能呢?因为这一节中,我是主要讲解Core Animation相关的图层动画,解释其执行过程及原理;大家在明白这里过程及原理后,适用UIView的block操作(它的内部实现就是借助图层动画,只是进行了一层封装)来实现动画,也是极好的。

2. 平移动画

动画代码如下:

// 1.创建动画对象
    CABasicAnimation *anim = [CABasicAnimation animation];
    
    // 2.设置动画对象
    // keyPath决定了执行怎样的动画, 调整哪个属性来执行动画
    anim.keyPath = @"position";
    //    anim.fromValue = [NSValue valueWithCGPoint:CGPointMake(0, 0)];
    // toValue : 最终变成什么值
    // byValue : 增加多少值
    anim.byValue = [NSValue valueWithCGPoint:CGPointMake(200, 200)];
    anim.duration = 2.0;
    
    /**让图层保持动画执行完毕后的状态**/
    // 动画执行完毕后不要删除动画
    anim.removedOnCompletion = NO;
    // 保持最新的状态(动画结束后的状态)
    anim.fillMode = kCAFillModeForwards;
    
    // 3.添加动画
    [self.layer addAnimation:anim forKey:nil];


动画效果如下:



3. 缩放动画

动画代码如下:

// 1.创建动画对象
    CABasicAnimation *anim = [CABasicAnimation animation];
    
    // 2.设置动画对象
    // keyPath决定了执行怎样的动画, 调整哪个属性来执行动画
    anim.keyPath = @"bounds";
    //    anim.fromValue = [NSValue valueWithCGPoint:CGPointMake(0, 0)];
    anim.toValue = [NSValue valueWithCGRect:CGRectMake(0, 0, 200, 200)];
    anim.duration = 2.0;
    
    /**让图层保持动画执行完毕后的状态**/
    // 动画执行完毕后不要删除动画
    anim.removedOnCompletion = NO;
    // 保持最新的状态
    anim.fillMode = kCAFillModeForwards;
    
    // 3.添加动画
    [self.layer addAnimation:anim forKey:nil];


动画效果如下:



4. 旋转动画

动画代码如下:

// 1.创建动画对象
    CABasicAnimation *anim = [CABasicAnimation animation];
    
    // 2.设置动画对象
    // keyPath决定了执行怎样的动画, 调整哪个属性来执行动画
    anim.keyPath = @"transform";
    //    anim.fromValue = [NSValue valueWithCGPoint:CGPointMake(0, 0)];
    anim.toValue = [NSValue valueWithCATransform3D:CATransform3DMakeRotation(M_PI, 1, -1, 0)];
    
    anim.duration = 2.0;
    
    anim.removedOnCompletion = NO;
    anim.fillMode = kCAFillModeForwards;
    
    // 3.添加动画
    [self.layer addAnimation:anim forKey:nil];


动画效果如下:



二、CAKeyframeAnimation

1. 连续动画

动画代码如下:

//CABasicAnimation  fromValue --> toValue
    CAKeyframeAnimation *anim = [CAKeyframeAnimation animation];
    
    anim.keyPath = @"position";
    
    NSValue *v1 = [NSValue valueWithCGPoint:CGPointZero];
    NSValue *v2 = [NSValue valueWithCGPoint:CGPointMake(100, 100)];
    NSValue *v3 = [NSValue valueWithCGPoint:CGPointMake(100, 200)];
    NSValue *v4 = [NSValue valueWithCGPoint:CGPointMake(250, 250)];
    anim.values = @[v1, v2, v3, v4];
    
    anim.duration = 2.0;
    
    anim.removedOnCompletion = NO;
    // 保持最新的状态
    anim.fillMode = kCAFillModeForwards;
    
    [self.redView.layer addAnimation:anim forKey:nil];


动画效果如下:



2. 缓冲动画

动画代码如下:

CAKeyframeAnimation *anim = [CAKeyframeAnimation animation];
    
    anim.keyPath = @"position";
    anim.removedOnCompletion = NO;
    anim.fillMode = kCAFillModeForwards;
    anim.duration = 4.0;
    
    CGMutablePathRef path = CGPathCreateMutable();
    CGPathAddEllipseInRect(path, NULL, CGRectMake(100, 100, 200, 200));
    anim.path = path;
    CGPathRelease(path);
    
    // 设置动画的执行节奏
    // kCAMediaTimingFunctionEaseInEaseOut : 一开始比较慢, 中间会加速,  临近结束的时候, 会变慢
    anim.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
    anim.delegate = self;
    
    [self.redView.layer addAnimation:anim forKey:nil];


动画效果如下:



注意到:代码中也可以对动画设置代理,用来监听动画的执行动作。比如下面代码:

#pragma mark - 动画的代理方法
#pragma mark 动画开始的时候调用
- (void)animationDidStart:(CAAnimation *)anim
{
    NSLog(@"animationDidStart");
}
#pragma mark 动画结束的时候调用
- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag
{
    NSLog(@"animationDidStop");
}


3. 抖动效果

动画代码如下:

- (void)viewDidLoad
{
    [super viewDidLoad];
    
    self.myImage.layer.cornerRadius = 15;
    self.myImage.layer.masksToBounds = YES;
    
}

- (IBAction)start {
    
    CAKeyframeAnimation *anim = [CAKeyframeAnimation animation];
    anim.keyPath = @"transform.rotation";
    
    anim.values = @[@(Angle(-5)),@(Angle(5)),@(Angle(-5))];
    
    anim.repeatCount = 10;
    
    anim.duration = 0.3;
    
    [self.myImage.layer addAnimation:anim forKey:@"Shake"];
    
}

- (IBAction)stop {
    [self.myImage.layer removeAnimationForKey:@"Shake"];
}


动画效果如下:



三、 CATransition

动画代码如下:

- (IBAction)prev {
    
    self.index--;
    
    if(self.index == -1){
        self.index = 8;
    }

    
    UIImage *prevImage = [UIImage imageNamed:[NSString stringWithFormat:@"%d.jpg",self.index+1]];
    
    self.myImage.image = prevImage;
    
    CATransition *anim = [CATransition animation];
    anim.type = @"pageUnCurl";
    anim.subtype = @"kCATransitionFromLeft";
    
    [self.myImage.layer addAnimation:anim forKey:nil];
    
}

- (IBAction)next {
    
    self.index++;
    
    if(self.index == 9){
        self.index = 0;
    }
    
    UIImage *nextImage = [UIImage imageNamed:[NSString stringWithFormat:@"%d.jpg",self.index+1]];
    
    self.myImage.image = nextImage;
    
    CATransition *anim = [CATransition animation];
    anim.type = @"pageCurl";
    anim.subtype = @"kCATransitionFromRight";
    
    [self.myImage.layer addAnimation:anim forKey:nil];
}


动画效果如下:



对代码中得type及subtype 进行说明(大家可以自己尝试看看效果):

type:

pageCurl 向上翻一页

pageUnCurl 向下翻一页

rippleEffect 滴水效果

suckEffect 收缩效果,如一块布被抽走

cube 立方体效果

oglFlip 上下翻转效果

subtype:

kCATransitionFade 交叉淡化过渡

kCATransitionMoveIn 新视图移到旧视图上面

kCATransitionPush 新视图把旧视图推出去

kCATransitionReveal 将旧视图移开,显示下面的新视图

四、 CAAnimationGroup

动画代码如下:

// 1.创建旋转动画对象
        CABasicAnimation *rotate = [CABasicAnimation animation];
        rotate.keyPath = @"transform.rotation";
        rotate.toValue = @(M_PI);
        
        // 2.创建缩放动画对象
        CABasicAnimation *scale = [CABasicAnimation animation];
        scale.keyPath = @"transform.scale";
        scale.toValue = @(0.0);
        
        // 3.平移动画
        CABasicAnimation *move = [CABasicAnimation animation];
        move.keyPath = @"transform.translation";
        move.toValue = [NSValue valueWithCGPoint:CGPointMake(100, 100)];
        
        // 4.将所有的动画添加到动画组中
        CAAnimationGroup *group = [CAAnimationGroup animation];
        group.animations = @[rotate, scale, move];
        group.duration = 5.0;
        group.removedOnCompletion = NO;
        group.fillMode = kCAFillModeForwards;
        
        [self.iconView.layer addAnimation:group forKey:nil];


动画效果如下:



总结:在本章节中,对Core Animation中所涉及的相关动画(平移,缩放,旋转,组合)进行了举例说明。在后面的几个章节中,我将逐步介绍动画的高级应用及应用案例。 To Be Continued...
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: