核心动画

核心动画

  • 动画可以大致分为两种,一种是UIView上的,一种是CALayer层的,其实本质都是基于CoreAnimation框架下,CALayer层的被称为核心动画,功能更强大,UIView的动画是基于核心动画的封装,用起来更加方便,由于CALayer层的核心动画是QuartzCore框架中的,可移植性高,OSX和ios上都可以用,但是在开发过程中用到的UIColor、UIImage是定义在UIKit框架中的,只能在iOS中使用,也就意味着利用核心动画的时候需要转换成CoreGraphics框架下的数据类型(即CGImageRef、CGColorRef)
核心动画_第1张图片
1.png

UIView上的动画

UIImageView的动画(gif动画)

//UIImageView的动画
- (void)gif
{
    NSMutableArray *arrayData = [NSMutableArray array];
    self.imageView = [[UIImageView alloc] initWithFrame:CGRectMake(100, 100, 100, 100)];
    for (int i = 0; i < 31; i++) {
        UIImage *image = [UIImage imageNamed:[NSString stringWithFormat:@"%d.jpg",(i + 1)]];
        [arrayData addObject:image];
    }
    //播放的图片
    self.imageView.animationImages = arrayData;
    //播放时间
    self.imageView.animationDuration = 1;
    //播放次数
    self.imageView.animationRepeatCount = INT_MAX;
    //开始播放
    [self.imageView startAnimating];
    //添加
    [self.view addSubview:self.imageView];
}

系统提供的风火轮动画(菊花)

//系统提供的菊花
- (void)activityIndicatorView
{
    //菊花
    self.acView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];
    self.acView.center = self.view.center;
    [self.view addSubview:self.acView];
    //修改颜色
    self.acView.color = [UIColor grayColor];
    //开始播放
    [self.acView startAnimating];
    //停止菊花
    self.acView.hidesWhenStopped = NO;
    //停止播放
//     [self.acView stopAnimating];
}

block动画(最简单最常用的动画,以animateWith开头,带有一个block)

//最常用最简单的动画(block方法)
- (void)blockView
{
    __block UIView *coustomView = [[UIView alloc] initWithFrame:CGRectMake(10, 10, 40, 40)];
    coustomView.backgroundColor = [UIColor greenColor];
    [self.view addSubview:coustomView];
    self.view.backgroundColor = [UIColor yellowColor];
    //1.动画的执行时间 2.动画的执行结果 3. 动画的执行完毕回调
    [UIView animateWithDuration:3 animations:^{
        self.view.backgroundColor = [UIColor redColor];
        coustomView.frame = CGRectMake(50, 50, 80, 20);
    } completion:^(BOOL finished) {
        //完成之后会来到这里
        NSLog(@"动画执行完毕");
    }];
}

与block效果一样的动画,创建方式不同(方法基本是对应的)

//跟block是对应的,效果是相同的,只是方式不一样
- (void)UIView
{
    UIView *coustomView = [[UIView alloc] initWithFrame:CGRectMake(100, 100, 200, 200)];
    coustomView.backgroundColor = [UIColor greenColor];
    [self.view addSubview:coustomView];
    //开始动画(id用来区分多个动画)
    [UIView beginAnimations:@"动画的id" context:@"附加的值"];



    //设置动画的属性(设置动画的属性一定要在开始动画和提交动画之间写)
    //时间
    [UIView setAnimationDuration:2];
    //动画的次数
    [UIView setAnimationRepeatCount:1];
    //(重复之后回去的渐变效果)
    [UIView setAnimationRepeatAutoreverses:YES];
    //设置动画的延迟时间
    [UIView setAnimationDelay:1.0];
    //设置代理
    [UIView setAnimationDelegate:self];
    //动画将要开始的时候执行的方法
    [UIView setAnimationWillStartSelector:@selector(startAction:context:)];
    //动画结束的时候执行的方法
    [UIView setAnimationDidStopSelector:@selector(stopAction:context:)];
    //运动轨迹
    [UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];



    //设置动画的最终结果
    coustomView.backgroundColor = [UIColor redColor];
    //提交动画
    [UIView  commitAnimations];
}
//开始执行的方法
- (void)startAction:(id)sender context:(id)context
{
    NSLog(@"%@  %@",sender,context);
}
//结束执行的方法
- (void)stopAction:(id)sender context:(id)context
{
    NSLog(@"%@  %@",sender,context);
}

关键帧动画(可以添加多个帧完成动画,多个帧意味着UIView的多个形态)


   __block UIView *coustomView = [[UIView alloc] initWithFrame:CGRectMake(100, 100, 200, 200)];
    coustomView.backgroundColor = [UIColor greenColor];
    [self.view addSubview:coustomView];
    //关键帧动画
    [UIView animateKeyframesWithDuration:5 delay:1 options:UIViewKeyframeAnimationOptionRepeat animations:^{
        //加了两个关键帧 , startTime是开始的时间,但是关键帧里的时间都是要乘以总时间的,也就是第一个帧的开始时间肯定为0,第二帧的开始时间应该是第一帧结束,relativeDuration是指本帧运行的时间,也就是说两个帧的运行时间加起来要等于1
        [UIView addKeyframeWithRelativeStartTime:0 relativeDuration:0.5 animations:^{
            coustomView.frame = CGRectMake(300, 300, 50, 50);
        }];
        [UIView addKeyframeWithRelativeStartTime:0.5 relativeDuration:0.5 animations:^{
            coustomView.frame = CGRectMake(100, 500, 100, 100);
        }];
    } completion:^(BOOL finished) {

    }];

spring动画(也就是弹簧效果+动画曲线)

//弹簧效果+动画曲线
- (void)springView
{
   __block UIView *coustomView = [[UIView alloc] initWithFrame:CGRectMake(100, 100, 200, 200)];
    coustomView.backgroundColor = [UIColor greenColor];
    [self.view addSubview:coustomView];
    //1.运行的时间 2.延迟 3.弹簧效果0-1(1是不弹) 4.初始速率 5.动画的模式(枚举)
    [UIView animateWithDuration:2 delay:1 usingSpringWithDamping: 0.1 initialSpringVelocity:12 options:UIViewAnimationOptionRepeat animations:^{
        coustomView.frame = CGRectMake(100, 400, 50, 50);
    } completion:^(BOOL finished) {

    }];
}

CALayer层的动画(CoreAnimation)

  • CoreAnimation是直接作用于layer层的动画
  • 开发步骤:
    • 1.首先得有CALayer
    • 2.初始化一个CAAnimation对象,并设置一些动画相关属性
    • 3.通过调用CALayer的addAnimation:forKey:方法,增加CAAnimation对象到CALayer中,这样就能开始执行动画了
    • 4.通过调用CALayer的removeAnimationForKey:方法可以停止CALayer中的动画
  • 隐式动画: 所有的非主层的layer,也就是手动创建的layer,都存在隐式动画,当对layer的部分属性(也就是注释中带有Animatable字样的)进行修改时会默认自动产生一些动画效果

CALayer概述

  • 在ios中所有能看见的控件都是UIView,但其实UIView是不能显示东西的,完全是因为layer层的原因,每一个UIView控件都至少有一个layer层(主层),主层是系统帮我们创建好的,但是我们可以在UIView上添加其他的layer层
  • CALayer显示原理:当UIView需要显示到屏幕上时,会调用drawRect:方法进行绘图,并且会将所有内容绘制在自己的图层上,绘图完毕后,系统会将图层拷贝到屏幕上,于是就完成了UIView的显示
  • CALayer的基本用法
//layer的属性和动画(只要被Animatable修饰的属性都可以动画)
- (void)layer
{
    UIView *coustomView = [[UIView alloc] initWithFrame:CGRectMake(100, 100, 100, 100)];
    [self.view addSubview:coustomView];
    //设置了layer的背景颜色
    coustomView.layer.backgroundColor = [UIColor redColor].CGColor;
    //设置layer描边的颜色
    coustomView.layer.borderColor = [UIColor yellowColor].CGColor;
    //设置layer描边的宽度
    coustomView.layer.borderWidth = 10.0f;
    //圆角的半径
    coustomView.layer.cornerRadius = 10;
    //阴影的颜色
    coustomView.layer.shadowColor = [UIColor blackColor].CGColor;
    //阴阳的偏移量
    coustomView.layer.shadowOffset = CGSizeMake(-5, -5);
    //阴影的透明度
    coustomView.layer.shadowOpacity = 0.5;
    //阴影的模糊成都
    coustomView.layer.shadowRadius = 3;
    [UIView animateWithDuration:2 animations:^{
        //旋转 1.旋转的角度 2.x轴是否转(0或1),3.y轴是否转(0或1),4.z轴是否转(0或1)
        coustomView.layer.transform = CATransform3DMakeRotation(M_PI, 1, 0, 0);
        //缩放 1.x缩放的比例 2.y缩放的比例3.z缩放的比例(没效果)
        coustomView.layer.transform = CATransform3DMakeScale(0, 0, 0);
        //平移的距离 1.x平移距离  2.y平移距离  3.z平移距离(没效果)
        coustomView.layer.transform =  CATransform3DMakeTranslation(100, 100, 100);
    }];
    //给UIView添加额外的layer层
    CALayer *layer = [CALayer layer];
    layer.frame = CGRectMake(0, 0, 100, 100);
    layer.backgroundColor = [UIColor cyanColor].CGColor;
    [coustomView.layer addSublayer:layer];
}
  • CALayer的position和anchorPoint属性
    • position:用来设置layer在父层中的位置,以父层的左上角为原点(0,0)
    • anchorPoint:称为锚点,是layer上的哪个点在position属性所指的位置显示,范围是(0,0)- (1,1),默认是(0.5,0.5)
    • 例如:position设置为(0,0),锚点不设置,也就是说layer的中心会放到(0,0)点,layer只显示了layer的1/4(右下角)
- (void)layerbuchong
{
    UIView *coustomView = [[UIView alloc] initWithFrame:CGRectMake(100, 100, 100, 100)];
    [self.view addSubview:coustomView];
    CALayer *layer = [[CALayer alloc] init];
    //layer的位置相对于锚点的
    layer.position = CGPointMake(0, 0);
    //锚点,默认0.5,0.5;
    layer.anchorPoint  =CGPointMake(0, 0);
    layer.backgroundColor = [UIColor yellowColor].CGColor;
    layer.frame = CGRectMake(0, 0, 100, 100);
    [coustomView.layer addSublayer:layer];
}

转场动画

  • 为layer层提供进入屏幕和移出屏幕的动画效果
  • 重要属性:
    • type:动画过渡类型
    • subtype:动画过渡方向
    • startProgress:动画起点(在整体动画的百分比)
    • endProgress:动画终点(在整体动画的百分比)
  • 系统给出的转场动画的type的样式
核心动画_第2张图片
2.png
static int i = 2;
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    // 转场代码
    if (i == 4) {
        i = 1;
    }
    // 加载图片名称
    NSString *imageN = [NSString stringWithFormat:@"%d",i];
    _imageView.image = [UIImage imageNamed:imageN];
    i++;


    // 转场动画(一定要和想要转场的代码放到一起)
    CATransition *anim = [CATransition animation];
    //动画过度的样式
    anim.type = @"pageCurl";
    //时间
    anim.duration = 2;
    //添加动画
    [_imageView.layer addAnimation:anim forKey:nil];
}
方法 说明
+ (void)transitionWithView:(UIView *)view duration:(NSTimeInterval)duration options:(UIViewAnimationOptions)options animations:(void (^)(void))animations completion:(void (^)(BOOL finished))completion; 使用UIView动画函数实现转场动画——单视图 duration:动画的持续时间 view:需要进行转场动画的视图 options:转场动画的类型 animations:将改变视图属性的代码放在这个block中 completion:动画结束后,会自动调用这个block
+ (void)transitionFromView:(UIView *)fromView toView:(UIView *)toView duration:(NSTimeInterval)duration options:(UIViewAnimationOptions)options completion:(void (^)(BOOL finished))completion; 使用UIView动画函数实现转场动画——双视图 duration:动画的持续时间 options:转场动画的类型 animations:将改变视图属性的代码放在这个block中 completion:动画结束后,会自动调用这个block

CABaseAnimation

  • 基础动画,通过设置keypath模仿KVC的形式去改变layer的某个属性,但是一次只能修改一个
  • 动画过程:随着动画的进行,在长度为duration的持续时间内,keyPath相应属性的值从fromValue渐渐的变为toValuekeyPath内容是CALayer的可动画Animatable属性如果fillMode=kCAFillModeForwards同时removedOnComletion=NO,那么在动画执行完毕后,图层会保持显示动画执行后的状态。但在实质上,图层的属性值还是动画执行前的初始值,并没有真正被改变。
- (void)baseAnimation
{
    UIView *coustomView = [[UIView alloc] initWithFrame:CGRectMake(100, 100, 100, 100)];
    coustomView.backgroundColor = [UIColor redColor];
    //设置锚点
    coustomView.layer.anchorPoint = CGPointMake(0, 0);
    [self.view addSubview:coustomView];
    //创建CABasicAnimation
    CABasicAnimation *baseAnimation  = [CABasicAnimation animationWithKeyPath:@"position"];
    //初始值(属性的最初值)
    baseAnimation.fromValue = [NSValue valueWithCGPoint:CGPointMake(100, 100)];
    //结束值(绝对的)
    //    baseAnimation.toValue = [NSValue valueWithCGPoint:CGPointMake(20, 20)];
    //结束值(相对的)
    baseAnimation.byValue = [NSValue valueWithCGPoint:CGPointMake(- 80, - 80)];
    //时间
    baseAnimation.duration = 2.0;
    //最终的位置
    coustomView.layer.position = CGPointMake(20, 20);
    //为layer层添加动画,后面的key可以传空,没用
    [coustomView.layer addAnimation:baseAnimation forKey:@"1"];

}

CAKeyframeAnimation

  • 关键帧动画,与UIView的关键帧动画模式一样,但也是通过基础动画的方式改变layer的某个属性
  • 主要属性的说明:
    • values:上述的NSArray对象。里面的元素称为“关键帧”(keyframe)。动画对象会在指定的时间(duration)内,依次显示values数组中的每一个关键帧
    • path:可以设置一个CGPathRef、CGMutablePathRef,让图层按照路径轨迹移动。path只对CALayer的anchorPoint和position起作用。如果设置了path,那么values将被忽略
    • keyTimes:可以为对应的关键帧指定对应的时间点,其取值范围为0到1.0,keyTimes中的每一个时间值都对应values中的每一帧。如果没有设置keyTimes,各个关键帧的时间是平分的
  • CABasicAnimation可看做是只有2个关键帧的CAKeyframeAnimation
//关键帧动画
- (void)CAKeyframeAnimation
{
    UIView *coustomView = [[UIView alloc] initWithFrame:CGRectMake(100, 100, 100, 100)];
    coustomView.backgroundColor = [UIColor redColor];
    coustomView.layer.anchorPoint = CGPointMake(0, 0);
    [self.view addSubview:coustomView];
    //关键帧动画
    CAKeyframeAnimation *key = [CAKeyframeAnimation animationWithKeyPath:@"position"];
    CGPoint point1 = CGPointMake(40,0);
    CGPoint point2 = CGPointMake(80,0);
    CGPoint point3 = CGPointMake(80,40);
    CGPoint point4 = CGPointMake(80,80);
    //关键帧的值
    key.values = @[[NSValue valueWithCGPoint:point1],[NSValue valueWithCGPoint:point2],[NSValue valueWithCGPoint:point3],[NSValue valueWithCGPoint:point4]];
    //添加时间
    key.duration = 10;
    //设置每一帧的运行时间
    key.keyTimes = @[@(0.7),@(0.1),@(0.1)];
    coustomView.layer.position = CGPointMake(80, 80);
    //添加动画
    [coustomView.layer addAnimation:key forKey:@"1"];
}

你可能感兴趣的:(核心动画)