iOS CoreAnimation 基础动画CABasicAnimation

本文参考:http://www.cnblogs.com/kenshincui/p/3972100.html#autoid-3-0-0总结的:

Core Animation

*

iOS 核心动画的实现

CoreAnimation (包含在Quartz Core 框架中), 在iOS核心动画分为几类(基础动画, 关键帧动画, 动画组, 转场动画, )

CAAnimation : 核心动画的基础类, 不能直接用, 负责动画运行时间吗速度的控制, 实现了CAMediaTiming协议

CAPropertyAnimation : 属性动画的基类 (通过属性进行动画设置, 注意是可动画属性), 不能直接使用

CAAnimationGroup : 动画组, 动画组是一种组合模式设计, 可以通过动画组来进行所有动画行为的统一控制, 组中所有动画效果可以并发执行(一起执行)

CATransition : 转场动画, 主要通过滤镜进行动画效果设置

CABasicAnimation : 基础动画, 通过属性修改进行动画参数控制, 只有初始状态和结束状态

CAKeyframeAnimation : 关键帧动画, 同样是通属性进行动画采纳数控制, 但同基础动画不同的是他可以多个状态控制

基础动画, 关键帧动画, 都属于属性动画, 就是通过修改属性值产生动画效果, 开发人员只需要设置初始值和结束值, 中间过程动画(补间动画)由系统自动计算产生, 和基础动画不同的是关键帧动画可以设置多个属性值, 每两个属性中间的补间动画由系统自定完成, 因此从这个角度基础动画是又来个关键帧的关键帧动画

直接上代码,注释很全, 简单易懂:

<span style="font-size:24px;">//
//  ViewController.m
//  CoreAnimation
//
//  Created by 帝炎魔 on 16/5/25.
//  Copyright © 2016年 帝炎魔. All rights reserved.
//

#import "ViewController.h"

#define WIDTH 50 // 宽度

@interface ViewController ()

@property (nonatomic, strong) CALayer *basicAniLayer;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.

    self.view.backgroundColor = [UIColor whiteColor];

    // 小圆球的动画
  //  [self drawMyLayer];

    // 使用代理方法绘图
   //  [self drawRollImageView];

    // 基础动画
    [self BasiceAnimation];

}

/**
 *  Core Animation
 *
    iOS 核心动画的实现

    CoreAnimation (包含在Quartz Core 框架中), 在iOS核心动画分为几类(基础动画, 关键帧动画, 动画组, 转场动画, )
    CAAnimation : 核心动画的基础类, 不能直接用, 负责动画运行时间吗速度的控制, 实现了CAMediaTiming协议
    CAPropertyAnimation : 属性动画的基类 (通过属性进行动画设置, 注意是可动画属性), 不能直接使用
    CAAnimationGroup : 动画组, 动画组是一种组合模式设计, 可以通过动画组来进行所有动画行为的统一控制, 组中所有动画效果可以并发执行(一起执行)
    CATransition : 转场动画, 主要通过滤镜进行动画效果设置
    CABasicAnimation : 基础动画, 通过属性修改进行动画参数控制, 只有初始状态和结束状态
    CAKeyframeAnimation : 关键帧动画, 同样是通属性进行动画采纳数控制, 但同基础动画不同的是他可以多个状态控制

    基础动画, 关键帧动画, 都属于属性动画, 就是通过修改属性值产生动画效果, 开发人员只需要设置初始值和结束值, 中间过程动画(补间动画)由系统自动计算产生, 和基础动画不同的是关键帧动画可以设置多个属性值, 每两个属性中间的补间动画由系统自定完成, 因此从这个角度基础动画是又来个关键帧的关键帧动画
 */

#pragma mark --- 基础动画
/**
 *  动画创建的步骤
 *
    1. 初始化动画并设置动画属性
    2. 设置动画属性初始值(可以省略), 结束值以及其他动画属性
    3. 给图层添加动画
 */
- (void)BasiceAnimation
{
    // 设置背景  (注意这个图片是在根视图)
    UIImage *backImage = [UIImage imageNamed:@"haha1"];
    self.view.backgroundColor = [UIColor colorWithPatternImage:backImage];

    // 自定义一个图层
    _basicAniLayer = [[CALayer alloc] init];
    _basicAniLayer.bounds = CGRectMake(0, 0, 50, 50 );
    _basicAniLayer.position = CGPointMake(50, 150);
    _basicAniLayer.contents = (id)[UIImage imageNamed:@"hudie"].CGImage;
    [self.view.layer addSublayer:_basicAniLayer];

}

#pragma mark ---- 移动动画
- (void)translationAnimation:(CGPoint)location
{
    // 1.创建动画并制定动画属性(通过keyPath 制定calayer的某个属性动画)
    CABasicAnimation *basicAnimation = [CABasicAnimation animationWithKeyPath:@"position"];

    // 2. 设置其他动画属性初始值和结束值
    basicAnimation.fromValue = [NSValue valueWithCGPoint:_basicAniLayer.position]; // 可以不设置, 默认为图层初始值状态
    basicAnimation.toValue = [NSValue valueWithCGPoint:location];

  NSLog(@"%f----%f", _basicAniLayer.position.x, _basicAniLayer.position.y);

    // 设置其他动画属性
    basicAnimation.duration = 2.0; // 动画时间2秒

   // basicAnimation.repeatCount = HUGE_VALF; // 设置动画重复的次数 HUGE_VALF代表无限大,无线重复动画
   // basicAnimation.removedOnCompletion = NO; // 运行一次是否移除动画

     /**
       *  这个动画存在一个问题: 动画结束后画图层回到了原来的位置, 当然用UIVieW封装的方法是没有这个问题的, 如何解决这个问题呢

       *   图层动画的本质就是将图层内部的内容转化为位图硬件操作形成一种动画效果, 其实图层本身并没有任何的变化,上面的动画中图层并没有因为动画效果而改变它的位置, (对于缩放动画其大小也是不会改变的), 所以在动画完成之后, 图层的属性也不会有任何变化, 我们可以在动画完成之后重新设置它的位置
       */

    basicAnimation.delegate = self;

    // 存储当前位置在动画结束后使用

    [basicAnimation setValue:[NSValue valueWithCGPoint:location] forKey:@"KCBasicAnimationLocation"];

    // 添加动画到图层, 注意key相当于给动画进行命名, 以后获得该动画是可以使用此名称获取
    [_basicAniLayer addAnimation:basicAnimation forKey:@"KCBasicAnimation_Translation"];

    // 在touch 点击事件中 执行动画

}

#pragma mark ---- 旋转动画
/**
 *  图层的形变都是基于锚点进行的
 *  通过keyPath 对锚点进行改变, 旋转的中心点就是图层的锚点
 */

- (void)rotationAnimation
{
     // 1. 创建动画并制定动画属性
    CABasicAnimation *basicAnimation  = [CABasicAnimation animationWithKeyPath:@"transform.rotation.y"];

    // 2. 设置动画属性初始值, 终止值
    basicAnimation.fromValue = [NSNumber numberWithInt:M_PI_2];
    basicAnimation.toValue = [NSNumber numberWithInt:M_PI_2 * 3];

    // 3. 设置其他动画属性
    basicAnimation.duration = 6.0;
    // 设置旋转后再旋转到原来的位置
    basicAnimation.autoreverses = true;

    basicAnimation.repeatCount = HUGE_VALF; // 设置无线循环

    // 动画运行一次不销毁, 默认为YES动画运行一次直接销毁
    basicAnimation.removedOnCompletion = NO;

    // 给图层添加动画 key相当于给动画命名, 可以通过key得到该动画
    [_basicAniLayer addAnimation:basicAnimation forKey:@"KCBasicAnimation_Rotation"];
}

/**
 *  核心动画的运行有一个媒体时间的概念, 假设将一个旋转动画设置旋转一周用时60秒的话, 那么当动画旋转90度的时候, 媒体时间就是15秒,如果此时要将动画暂停只需要让媒体时间偏移量设置为15秒即可, 并把动画运行速度设置为0让它停止运动,类似的, 如果又过了60妙需要恢复动画(此时媒体时间为75妙), 这时只要将动画开始开始时间设置为当前媒体时间75秒减去暂停时的时间*也就是之前定格动画时的偏移量15妙. 75-15=60秒.
    这时对暂停动画和恢复动画的其实是动画速度的调整,
    媒体时间偏移量以及恢复时的开始时间设置主要为了让动画更加连贯.

 *
 *  

 */

#pragma mark --- 动画暂停
- (void)animationPause
{
    // 取得指定图层动画的媒体时间, 后面参数用于指定子图层, 这里不需要
    CFTimeInterval interval = [_basicAniLayer convertTime:CACurrentMediaTime() fromLayer:nil];
    // 设置时间偏移量, 保证暂停时停留在旋转的位置
    [_basicAniLayer setTimeOffset:interval];
    // 速度设置为0 暂停动画
    _basicAniLayer.speed = 0;
}

#pragma mark --- 动画恢复
- (void)animationResume
{
    // 取得指定图层动画的媒体时间, 后面的参数用于指定子图层, 这里不需要
    CFTimeInterval interval = CACurrentMediaTime() - _basicAniLayer.timeOffset;
    // 设置时间偏移量
    _basicAniLayer.timeOffset = 0;
    // 设置开始时间
    _basicAniLayer.beginTime = interval;
    // 设置动画速度, 开始运动
    _basicAniLayer.speed = 1.0;
}

#pragma mark ---- 动画代理方法
// 动画开始的时候
-(void)animationDidStart:(CAAnimation *)anim
{
    NSLog(@"animation (%@) start.\r_layer.frame=%@", anim, NSStringFromCGRect(_basicAniLayer.frame));
    // 通过前面设置的key获得动画
    // 设置动画的图层 调用 animationForKey:@"图层设置的动画Key"
    NSLog(@"%@", [_basicAniLayer animationForKey:@"KCBasicAnimation_Translation"]);
}

// 动画结束的时候
-(void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag
{
    /**
     *  还有一个问题就是动画运行完成后会重新从起始点运动到终点, 这个问题产生原因就是前面提到的,对于非根视图, 设置图层的可动画属性(在动画结束后重新设置了position, 而position是可动画的属性,会产生动画效果),解决这个问题就是在重新设置这个图层的position关闭图层隐式动画

     *
     *  要关闭隐式动画需要用到动画事务CATransaction, 在事务内将隐式动画关闭

        1. 开启事务  [CATransaction begin];
        2. 禁用隐式动画  [CATransaction setDisableActions:YES];
        3. 事务提交    [CATransaction commit];
     */
      NSLog(@"animation (%@) start.\r_layer.frame=%@", anim, NSStringFromCGRect(_basicAniLayer.frame));

    // 开启事务
    [CATransaction begin];
    // 禁用隐式动画
    [CATransaction setDisableActions:YES];

    _basicAniLayer.position = [[anim valueForKey:@"KCBasicAnimationLocation"] CGPointValue];

    CABasicAnimation *animation = (CABasicAnimation *)[anim valueForKey:@"KCBasicAnimation_Translation"];
    animation.fromValue = [NSValue valueWithCGPoint:[[anim valueForKey:@"KCBasicAnimationLocation"] CGPointValue]];;
    // 提交事务
    [CATransaction commit];

    // 暂停动画
    [self animationPause];
}

#pragma mark --- 使用代理方法绘图
- (void)drawRollImageView
{
    // 自定义图层
    CALayer *layer = [[CALayer alloc] init];
    layer.bounds = CGRectMake(0, 0, 150, 150);
    layer.position = CGPointMake(160, 200);
    layer.backgroundColor = [UIColor redColor].CGColor;
    layer.cornerRadius = 150 / 2;

    // 需要裁剪圆角多余的部分
    layer.masksToBounds = YES;
    // 如果设置多余图片裁剪的效果的话, 无法设置图片的阴影
    // 如果想设置阴影效果的话, 再添加一个layer 与该图片图层等大, 再设置图层
    // 下面的图层负责绘制阴影, 上面的图层负责显示图片

    // 注意 : 利用图层形变解决图像倒立问题  没必要走drawRect的方法
    // layer.transform = CATransform3DMakeRotation(M_PI, 1, 0, 0);

    // 注意 : 如果只是显示一张图片在图层中, 没必要麻烦, 直接设置图层contents就可以了
    // 不会牵制到绘图, 就不会涉及到倒立的问题

    // 设置内容
//    UIImage *image = [UIImage imageNamed:@"jiqimao"];
//    [layer setContents:(id)image.CGImage];

    // 设置图层代理
    layer.delegate = self;
    // 添加图层到根图层
    [self.view.layer addSublayer:layer];

    // 调用图层setNeedDisplay, 否则代理方法不会走
    [layer setNeedsDisplay];

}

// layer [layer setNeedsDisplay]的代理方法 一定要调用这个方法
- (void)drawLayer:(CALayer *)layer inContext:(CGContextRef)ctx
{
    // layer 就是设置代理的那个图层
  //  CGContextSaveGState(ctx);

    // 图形上下文形变, 解决图片倒立问题
    CGContextScaleCTM(ctx, 1, -1);
    CGContextTranslateCTM(ctx, 0, -150);

    UIImageView *imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"jiqimao"]];
   // imageView.bounds = CGRectMake(0, 0, 150, 150);

    // 注意这个位置是相对图层而言, 不是屏幕
    CGContextDrawImage(ctx, CGRectMake(0, 0, 150, 150),imageView.image.CGImage);

   // CGContextRestoreGState(ctx);

}

#pragma mark 绘制圆形图层, 创建动画
-(void)drawMyLayer{
    CGSize size=[UIScreen mainScreen].bounds.size;

    //获得根图层
    CALayer *layer=[[CALayer alloc]init];
    //设置背景颜色,由于QuartzCore是跨平台框架,无法直接使用UIColor
    layer.backgroundColor=[UIColor colorWithRed:0 green:146/255.0 blue:1.0 alpha:1.0].CGColor;
    //设置中心点
    layer.position=CGPointMake(size.width/2, size.height/2);
    //设置大小
    layer.bounds=CGRectMake(0, 0, WIDTH,WIDTH);
    //设置圆角,当圆角半径等于矩形的一半时看起来就是一个圆形
    layer.cornerRadius=WIDTH/2;
    //设置阴影
    layer.shadowColor=[UIColor grayColor].CGColor;
    layer.shadowOffset=CGSizeMake(2, 2);
    layer.shadowOpacity=.9;
    //设置边框
    //    layer.borderColor=[UIColor whiteColor].CGColor;
    //    layer.borderWidth=1;

    //设置锚点
    //    layer.anchorPoint=CGPointZero;

    [self.view.layer addSublayer:layer];
}

#pragma mark --- touch方法
// 点击放大效果
-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{

    // 1. 点击移动动画
//    UITouch *touch=[touches anyObject];
//    CALayer *layer=[self.view.layer.sublayers lastObject];
//    CGFloat width=layer.bounds.size.width;
//    if (width==WIDTH) {
//        width=WIDTH*4;
//    }else{
//        width=WIDTH;
//    }
//    layer.bounds=CGRectMake(0, 0, width, width);
//    layer.position=[touch locationInView:self.view];
//
//    layer.cornerRadius=width/2;

    // 2. 基础动画
    UITouch *touch = [touches anyObject];
    CGPoint point = [touch locationInView:self.view];

    // 判断是否已创建过动画, 如果已经创建则不创建动画
    CAAnimation *animation = [_basicAniLayer animationForKey:@"KCBasicAnimation_Translation"];
    if (animation) {
        if (_basicAniLayer.speed == 0) {
            [self animationResume];
        } else {
            [self animationPause];
        }
    } else {
        // 创建并开始动画
        [self translationAnimation:point];

        [self rotationAnimation];
    }

}

@end

</span>
时间: 2024-10-11 17:58:11

iOS CoreAnimation 基础动画CABasicAnimation的相关文章

核心动画基础动画(CABasicAnimation)关键帧动画

1.在iOS中核心动画分为几类: 基础动画(CABasicAnimation) 关键帧动画(CAKeyframeAnimation) 动画组(CAAnimationGroup) 转场动画(CATransition) 2.CAAnimation:核心动画的基础类,不能直接使用,负责动画运行时间,速度的控制,本身实现了CAMediaTiming协议 3.CAPropertyAnimation:属性动画也是基类(通过属性进行动画设置,注意是动画属性),不能直接使用. CABasicAnimation:

iOS CoreAnimation(核心动画二)

CATransition :转场动画  翻转动画 @interface ViewController () - (IBAction)previous:(UIButton *)sender; - (IBAction)next:(UIButton *)sender; @property (strong, nonatomic) IBOutlet UIImageView *iconView; @property(nonatomic,assign)int index;//当前图片的索引 @property

IOS CoreAnimation

@property (weak, nonatomic) IBOutlet UIView *redView;@property (weak, nonatomic) IBOutlet UILabel *label; #pragma mark - CoreAnimation //基础动画 - (IBAction)CABasicAnimation:(UIButton *)sender { //参数需要是layer的属性,或者是属性的属性的名字 CABasicAnimation *basic = [CAB

iOS开发-动画总结

一.简介 IOS 动画主要是指Core Animation框架.官方使用文档地址为:Core Animation Guide.Core Animation是IOS和OS X平台上负责图形渲染与动画的基础框架.Core Animation可以作用与动画视图或者其他可视元素,为你完成了动画所需的大部分绘帧工作.你只需要配置少量的动画参数(如开始点的位置和结束点的位置)即可使用Core Animation的动画效果.Core Animation将大部分实际的绘图任务交给了图形硬件来处理,图形硬件会加速

CoreAnimation 核心动画

- (void)createBaseAnimation{ //基础动画 CABasicAnimation *animation = [CABasicAnimation animation]; animation.keyPath = @"bounds"; //    animation.fromValue = [NSValue valueWithCGRect:CGRectMake(0, 0, 300, 300)];//默认为现在的状态 animation.toValue = [NSVal

IOS中的动画——Core Animation

一.基础动画 CABasicAnimation 1 //初始化方式 CABasicAnimation * cabase=[CABasicAnimation animation]; 2 //通过keyPath设置需要实现动画的属性,此处设为bounds [email protected]"bounds"; 3 //通过toValue设置动画结束时候的状态 cabase.toValue=[NSValue valueWithCGRect:CGRectMake(0, 0, 10, 100)];

ios(CoreAnimation核心动画 一) CABasicAnimation动画与锚点

一.position和anchorPoint position:用来设置CALayer在父层中的位置,以父层的左上角为原点(0, 0) anchorPoint(锚点): 称为"定位点"."锚点" 决定着CALayer身上的哪个点会在position属性所指的位置 以自己的左上角为原点(0, 0) 它的x.y取值范围都是0~1,默认值为(0.5, 0.5) 推荐一个连接:http://www.cnblogs.com/wendingding/p/3800736.html

ios(CoreAnimation核心动画 ) CABasicAnimation动画与锚点

一.position和anchorPoint position:用来设置CALayer在父层中的位置,以父层的左上角为原点(0, 0) anchorPoint(锚点): 称为“定位点”.“锚点” 决定着CALayer身上的哪个点会在position属性所指的位置 以自己的左上角为原点(0, 0) 它的x.y取值范围都是0~1,默认值为(0.5, 0.5) 推荐一个连接:http://www.cnblogs.com/wendingding/p/3800736.html讲的非常详细,而且有图视,默认

猫猫学IOS(三十九)UI之核心动画之CABasicAnimation(基础动画)

猫猫分享,必须精品 原创文章,欢迎转载.转载请注明:翟乃玉的博客 地址:http://blog.csdn.net/u013357243?viewmode=contents 一.CABasicAnimation简介 CAPropertyAnimation的子类 属性解析: fromValue:keyPath相应属性的初始值 toValue:keyPath相应属性的结束值 随着动画的进行,在长度为duration的持续时间内,keyPath相应属性的值从fromValue渐渐地变为toValue 如