OC动画的几种实现方式

一. 序列帧动画

序列帧动画和我们小时候看的小人书是一样的,由连续的很多张的画面组成,每一张都与前一张稍有不同,快速翻动的时候就是一个动画了。序列帧动画就是通过UIImageView,快速一帧一帧的播放图片实现的动画效果。

    NSMutableArray *imageArray = [NSMutableArray array];
    for (int i=1; i<50; i++) {
        NSString *source = [[NSBundle mainBundle] resourcePath];
        NSString *imgPath = [source stringByAppendingPathComponent:[NSString stringWithFormat:@“gifImage%d”, i]];
        [imageArray addObject:[UIImage imageWithContentsOfFile:imgPath]];
    }
    [self.alignmentView setAnimationImages:imageArray];
    [self.alignmentView setAnimationRepeatCount:1];
    [self.alignmentView setAnimationDuration:4];
    [self.alignmentView startAnimating];
bicycle.gif

代码中使用imageWithContentsOfFile而没有使用imageNamed的原因:
imageWithContentsOfFile不会将图片缓存,图片所占内存在使用后就会清除
imageNamed使用的图片会缓存下来,运行内存占用比较高

二. UIView动画

UIView动画实际上就是UIView对核心动画的封装,通过更简单的设置就可以实现很多常用的动画效果。UIView动画是作用在CALayer上的,可以用来做动画的属性有frame,bounds,alpha,transform,backgroundColor,基本上能满足大多数的动画需要。

    [UIView animateWithDuration:4 animations:^{
        //center -- 视图位置
        CGPoint center = self.animationView.center;
        center.y += 100;
        self.animationView.center = center;
        //alpha -- 透明度
        self.animationView.alpha = 0.2;
        //transform -- 旋转加缩放
        self.animationView.transform = CGAffineTransformRotate(self.animationView.transform, M_PI_4);
        self.animationView.transform = CGAffineTransformScale(self.animationView.transform, 0.5, 0.5);
    }];
uiviewAnimation.gif

同样的还有:

    //可以检测动画结束
    [UIView animateWithDuration:4 animations:^{
        //动画设置
    } completion:^(BOOL finished) {
        //动画结束后执行的操作
    }];
    //可以设置延迟时间,以及检测动画执行结束
    [UIView animateWithDuration:4 delay:1 options:UIViewAnimationOptionAutoreverse animations:^{
        //动画设置
    } completion:^(BOOL finished) {
        //动画结束后执行的操作
    }];
    //弹性动画,参数说明:01 持续时间, 02 延迟时间, 03 弹簧强度 0.0 - 1.0, 04 开始变化速度, 05 动画效果参数
    [UIView animateWithDuration:10 delay:0 usingSpringWithDamping:0.05 initialSpringVelocity:1 options:UIViewAnimationOptionCurveEaseInOut animations:^{
        //动画设置
    } completion:^(BOOL finished) {
        //动画结束执行的操作
    }];

三. 核心动画

核心动画就是设置动画的运动路径或关键点,然后将这些属性值添加到CALayer,再设置动画的执行时间,方向,代理等。
核心动画的结构:

核心动画类结构.png

核心动画层次结构:
层次结构.png

CAAnimation是所有动画对象的父类,遵守CAMediaTiming协议,实现的功能是控制动画时间,重复次数,填充模式等,是一个抽象类,不能直接使用。
核心动画类中可以直接使用的类有:
CABasicAnimation 基本动画
CAKeyframeAnimation 关键帧动画
CASpringAnimation 弹性动画
CATransition 转场动画
CAAnimationGroup 动画组

1. CABasicAnimation

CABasicAnimation可以看作是只有两个关键点的CAKeyFrameAnimation,动画的效果就是从起点进行到终点。
对图形位置做动画:

    //因为没有设置动画的结束状态,默认情况下动画执行结束图形会回到初始位置
    CABasicAnimation *basicAnimation = [CABasicAnimation animationWithKeyPath:@"position.y"];
    basicAnimation.fromValue = @(self.animationView.center.y);
    basicAnimation.toValue = @(self.animationView.center.y + 30);
    basicAnimation.repeatCount = 3;
    basicAnimation.duration = 1;
    [self.animationView.layer addAnimation:basicAnimation forKey:nil];
positionY.gif

图形的旋转动画:

    CABasicAnimation *basicAnimation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.y"];
    basicAnimation.fromValue = @(0);
    basicAnimation.toValue = @(M_PI);
    basicAnimation.repeatCount = 1;
    basicAnimation.duration = 1;
    //若要将removedOnCompletion设置为NO,fillMode必须设置为kCAFillModeForwards
    basicAnimation.fillMode = kCAFillModeForwards;
    //若要将removedOnCompletion设置为NO表示动画结束后图形不会回到初始状态
    basicAnimation.removedOnCompletion = NO;
    [self.animationView.layer addAnimation:basicAnimation forKey:nil];
transformRotationY.gif

transformRotationX.gif
transformRotationZ.gif

2. CAKeyframeAnimation

values:设置一个关键帧的对象数组,每个元素都是一个关键帧,动画在对应的时间段内执行数组中的每一个关键帧动画
path:动画路径对象,为动画指定一个路径,动画图形沿着路径移动
keyTimes:设置关键帧之间的动画所占用的动画时长比例(0-1),若不设置,则每一帧的时间平分
可以做动画的关键帧有:anchorPoint backgroundColor borderColor borderWidth bounds contents contentsRect cornerRadius doubleSided frame hidden mask maskToBounds opacity position shadowColor shadowOffset shadowOpacity shadowPath shadowRadius sublayers sublayerTransform transform

    CAKeyframeAnimation *keyAnimation = [CAKeyframeAnimation animationWithKeyPath:@"position"];
    //确定路径上的几个锚点
    NSValue *value1 = [NSValue valueWithCGPoint:self.animationView.center];
    NSValue *value2 = [NSValue valueWithCGPoint:CGPointMake(self.view.bounds.size.width/2 + 100, 300)];
    NSValue *value3 = [NSValue valueWithCGPoint:CGPointMake(self.view.bounds.size.width/2, 400)];
    NSValue *value4 = [NSValue valueWithCGPoint:CGPointMake(self.view.bounds.size.width/2 - 100, 300)];
    //将几个锚点连接起来绘制动画的路径
    keyAnimation.values = @[value1,value2,value3,value4,value1];
    keyAnimation.duration = 3;
    keyAnimation.repeatCount = 2;
    [self.animationView.layer addAnimation:keyAnimation forKey:nil];
positionValues.gif
    CAKeyframeAnimation *keyAnimation = [CAKeyframeAnimation animationWithKeyPath:@"position"];
    UIBezierPath *circlePath = [UIBezierPath bezierPathWithArcCenter:CGPointMake(self.animationView.center.x, self.animationView.center.y+100) radius:100 startAngle:-M_PI_2 endAngle:3.0*M_PI_2 clockwise:YES];
    keyAnimation.path = circlePath.CGPath;
    keyAnimation.repeatCount = 2;
    keyAnimation.duration = 2;
    [self.animationView.layer addAnimation:keyAnimation forKey:nil];
positionPath.gif

3. CASpringAnimation

UIView的弹性动画就是对CASpringAnimation的简单封装,可以完成简单的弹性动画,CASpringAnimation功能更强大,能够实现更复杂的弹性动画效果。重要属性:
mass:质量,质量越大,弹簧的惯性越大
stiffness:弹性系数,弹性系数越大,运动越快
damping:阻尼系数,阻尼越大,弹簧的运动停止越快
initialVelocity:初始速度
settlingDuration:执行时间

    CASpringAnimation *springAnimation = [CASpringAnimation animationWithKeyPath:@"bounds"];
    springAnimation.mass = 1;
    springAnimation.stiffness = 1000;
    springAnimation.damping = 20;
    springAnimation.initialVelocity = 50;
    springAnimation.duration = springAnimation.settlingDuration;
    springAnimation.fromValue = @(self.animationView.bounds);
    CGRect newBounds = CGRectMake(self.animationView.bounds.origin.x, self.animationView.bounds.origin.y, self.animationView.bounds.size.width+80, self.animationView.bounds.size.height);
    springAnimation.toValue = @(newBounds);
    springAnimation.fillMode = kCAFillModeForwards;
    springAnimation.removedOnCompletion = NO;
    springAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
    [self.animationView.layer addAnimation:springAnimation forKey:nil];
springScale.gif
springPosition.gif

4. CATransition

CATransition提供了四种动画效果,私有的几种动画效果已经禁止使用。通过type属性设置动画的类型,通过subtype设置动画的方向。

    CATransition *transition = [CATransition animation];
    //公开kCATransitionMoveIn,Push,Reveal,Fade
    //私有cube,suckEffect,oglFlip,rippleEffect,pageCurl,pageUnCurl
    transition.type = kCATransitionPush;
    transition.subtype = kCATransitionFromLeft;
    transition.duration = 0.5;
    UIColor *red = [UIColor redColor];
    UIColor *orange = [UIColor orangeColor];
    UIColor *yellow = [UIColor yellowColor];
    UIColor *green = [UIColor greenColor];
    UIColor *blue = [UIColor blueColor];
    UIColor *purple = [UIColor purpleColor];
    NSArray *colorArr = @[red,orange,yellow,green,blue,purple];
    self.animationView.backgroundColor = colorArr[count];
    [self.animationView.layer addAnimation:transition forKey:nil];
    count = count==5?0:count+1;
transitionPush.gif
transitionMoveIn.gif
transitionReveal.gif
transitionFade.gif

5. CAAnimationGroup

组动画可以将多个动画效果一起添加到CALayer上,多个动画同时执行,实现更复杂更生动的效果。

    //圆形路径的动画
    CAKeyframeAnimation *keyAnimation = [CAKeyframeAnimation animationWithKeyPath:@"position"];
    UIBezierPath *circlePath = [UIBezierPath bezierPathWithArcCenter:CGPointMake(self.animationView.center.x, self.animationView.center.y+100) radius:100 startAngle:-M_PI_2 endAngle:3.0*M_PI_2 clockwise:YES];
    keyAnimation.path = circlePath.CGPath;
    //大小动画
    CAKeyframeAnimation *keyAnimation2 = [CAKeyframeAnimation animationWithKeyPath:@"transform.scale"];
    keyAnimation2.values = @[@(1.0),@(0.9),@(0.8),@(0.7),@(0.6),@(0.5),@(0.6),@(0.7),@(0.8),@(0.9),@(1.0)];
    //创建组动画
    CAAnimationGroup *group = [CAAnimationGroup animation];
    group.animations = @[keyAnimation,keyAnimation2];
    group.duration = 5;
    group.repeatCount = 3;
    [self.animationView.layer addAnimation:group forKey:nil];
groupAnimation.gif

以上就是对我们对几种经常使用的动画形式的简单介绍,使用这些方式能够帮助我们实现大多数简单的动画效果。

参考:iOS动画篇:核心动画

你可能感兴趣的:(OC动画的几种实现方式)