核心动画

1. 核心动画基本概念

  1> 核心动画(Core Animation)是一组非常强大的动画处理API,使用它能够做出非常绚丽的动画效果,而且往往事半功倍

  2> 使用它需要先添加QuartzCore.framework和引用对应的框架<QuartzCore/QuartzCore.h>。Xcode5就不用在添加了,会自动添加

  3> 开发步骤

    1) 初始化一个动画对象(CAAnimation)

    2) 设置一些相关属性。CALayer中很多属性都可以通过CAAnimation属性来设置动画效果,包括:opacity、position、transform、bounds、contents等(可以在API文档中搜索:CALayer Animatable Properties)

    3) 添加动画对象到层(CALayer)中,开始执行动画

      a) 通过调用CALayer的addAnimation:forKey:添加动画到层(CALayer)中,这样就能触发动画了

      b) 通过调用removeAnimationForKey可以停止层中的动画。

      3) Core Animation的动画执行过程都是在后台执行的,不会阻塞主线程

  4> CAAnimation继承结构

 

2. CAAnimation

  1> CAAnimation是所有动画对象的父类,负责控制动画的持续时间和速度,是个抽象类,不能直接使用,应该使用它具体子类

  2> 属性说明:(红色代表来自CAMediaTiming协议的属性)

    1) duration: 动画持续时间

    2) repeatCount: 重复次数,无限循环可以使用HUGE_VALF或者MAXFLOAT

    3) repeatDuration: 每次重复的时间间隔

    4) removeOnCompletion: 动画执行完毕后就从图层上移除,图形会恢复到动画执行之前的状态,默认为YES。如果想让图形显示动画执行后的状态,需要将其设置为NO,另外还要设置fillMode为kCAFillModeForwards

    5) fillMode: 决定当前对象在非active时间段的行为。比如动画开始之前,或者开始之后。

    6) beginTime: 用来设置动画延迟执行时间,若需延迟2s,就设置为CACurrentMediaTime() + 2 , CACurrentMediaTime()为图层的当前时间

    7) timingFunction: 速度控制函数,控制动画运行节奏

    8) delegate: 动画代理

  3> 动画填充模式(fillMode)

    1) fillMode属性值(如果想要fillMode有效,最好设置removeOnCompletion为NO)

    2) kCAFillModeRemoved: 这个是默认值,动画开始前和动画结束后,动画对layer都没有影响,动画结束后,layer会恢复到之前的状态。

    3) kCAFillModeForwards: 当动画结束后,layer会一直保持在动画最后的状态

    4) kCAFillModeBackwards:在动画开始之前,只需将动画加入了一个Layer,layer便立即进入动画的初始化状态并等待动画开始。

    5) kCAFillModeBoth:这个其实就是上面两个的合成,动画加入layer后,但没有开始之前,layer便处于动画初始状态,动画结束后layer保持动画最后状态。

  4> 速度控制函数(CAMediaTimingFunction)

    1) kCAMediaTimingFunctionLiner(线性):匀速,给用户一个相对静态的感觉。

    2) kCAMediaTimingFunctionEaseIn(渐进):动画缓慢进入,然后加速离开

    3) kCAMediaTimingFunctionEaseOut(渐出):动画全速进入,然后减速的到达目的地

    4) kCAMediaTimingFunctionEaseInEaseOut(渐进渐出):动画缓慢进入,中间加速,然后减速的到达目的地。这个是默认的动画行为。

  5> 动画代理方法

    CAAnimation在分类中定义了代理方法:

    @interface NSObject (CAAnimationDelegate)

    #pragma mark 动画开始

    - (void) animationDidStart:(CAAnimation *) anim;

    #pragma mark 动画结束

    - (void) animationDidStop:(CAAnimation *) anim finished:(BOOL) flag;

    @end

  6> CALayer上动画的暂停和恢复方法

    #pragma mark 暂停CALayer的动画

    - (void) pauseLayer:(CALayer*)layer{

      CFTimeInterval pausedTime = [layer convertTime:CACurrentMediaTime() fromLayer:nil];

      // 让CALayer的时间停止运动

      layer.speed = 0.0f;

      // 让CALayer的时间停留在pauseTime这个时间

      layer.timeOffset = pausedTime;

    }

    #pragma mark 恢复CALayer的动画

    - (void) resumeLayer:(CALayer*)layer{

      CFTimeInterval pausedTime = layer.timeOffset;

      //1. 让CALayer的时间继续行走

      layer.speed = 1.0f;

      //2. 取消上次记录的停留时间

      layer.timeOffset = 0.0f;

      //3. 取消上次设置的时间

      layer.beginTime = 0.0f;

      //4. 计算暂停的时间(这里也可以用CACurentMediaTime() - pausedTime)

      CFTimeInterval timeSincePause = [layer convertTime:CACurrentMediaTime() fromLayer:nil] = pausedTime;

      //5. 设置相对于夫坐标系的开始时间(往后退timeSincePause)

      layer.beginTime = timeSincePause;

    }

3. CAPropertyAnimation

  1> CAPropertyAnimation是CAAnimation的子类,也是个抽象类,要想创建动画对象,就要使用它的两个子类(CABasicAnimation、CAKeyframeAnimation)

  2> 属性说明:

    1) keyPath:通过指定CALayer的属性名称,从而达到动画效果:比如指定@"position",执行平移的效果

4. CABasicAnimation

  1> CApropertyAnimation的子类

  2> 属性说明:

    1) fromValue: keyPath相应属性的初始值

    2) toValue:keyPath相应属性的结束值

  3> 动画过程说明:

    1) 随着动画的进行,在时长为duration的时间内,kayPath相对应属性的值从fromValue渐渐变到toValue

    2) keyPath内容是CALayer的可动画Animatable属性

    3) 如果fillMode = KCAFillModeForwards同时removeOnComletion=NO,那么在动画执行完毕后,图层会保留动画执行后的状态。但实质上,图层的属性值还是动画执行前的初始值,并没有正真被改变

  【示例1 - 使用CABasicAnimation完成平移、缩放、旋转动作】

#import <UIKit/UIKit.h>
@interface MainViewController : UIViewController
#pragma mark - 动画的暂停和恢复
#pragma mark 暂停动画
-(void) pauseAnimation;
#pragma mark 恢复动画
-(void) resumeAnimation;
@end
#import "MainViewController.h"

@interface MainViewController ()
@property (weak,nonatomic) UIView *myView;
@end

@implementation MainViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    
    UIView *myView = [[UIView alloc]initWithFrame:CGRectMake(50, 50, 100, 100)];
    [myView setBackgroundColor:[UIColor redColor]];
    
    [self.view addSubview:myView];
    
    self.myView = myView;
}

#pragma mark -动画代理方法
#pragma mark 动画开始(极少用)
-(void) animationDidStart:(CAAnimation *)anim{
    NSLog(@"动画开始");
}

#pragma mark 动画结束(通常在动画结束后,设置动画后续处理)
-(void) animationDidStop:(CAAnimation *)anim finished:(BOOL)flag{
    NSLog(@"动画结束");
    
    NSString *animationType = [anim valueForKeyPath:@"animationType"];
    if ([animationType isEqualToString:@"translationTo"]) {
        //1. 通过键值取出需要移动到的目标点
        CGPoint targetPoint = [[anim valueForKeyPath:@"targetPoint"]CGPointValue];
        //2. 设置myView的坐标点
        [self.myView setCenter:targetPoint];
    }
    
    NSLog(@"%@",NSStringFromCGPoint(self.myView.layer.position));
}

#pragma mark - touch 事件
-(void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
    UITouch *touch = [touches anyObject];
    CGPoint location = [touch locationInView:self.view];
    if ([touch view] == self.myView) {
        NSLog(@"点击了myView");
    }
    
    //1. 平移动画
    //[self translationTo:location];
    //2. 缩放动画
    //[self scaleAnimation];
    //3. 旋转动画
    CAAnimation *anim = [self.myView.layer animationForKey:@"rotationAnim"];
    if (anim) {
        if (self.myView.layer.speed == 0) {
            [self resumeAnimation];
        }else{
            //[self.myView.layer removeAllAnimations];
            [self pauseAnimation];
        }
    }else{
        [self rotationAnimation];
    }
}

#pragma mark - 动画的暂停和恢复
#pragma mark 暂停动画
-(void) pauseAnimation{
    // 1. 取出当前动画的时间点,就是要暂停的时间点
    CFTimeInterval pausedTime = [self.myView.layer convertTime:CACurrentMediaTime() fromLayer:nil];
    // 2. 设置动画的时间偏移量,指定时间偏移量的目的是让动画定格在该时间点
    [self.myView.layer setTimeOffset:pausedTime];
    // 3. 将动画的速度置为0,动画默认速度是1
    [self.myView.layer setSpeed:0.0f];
}

#pragma mark 恢复动画
-(void) resumeAnimation{
    //1. 取出动画的暂停点
    CFTimeInterval pausedTime = [self.myView.layer timeOffset];
    //2. 将动画偏移量清空
    [self.myView.layer setTimeOffset:0.0f];
    //3. 将动画速度还原为1
    [self.myView.layer setSpeed:1.0f];
    //4. 根据媒体时间准确的计算出动画延迟执行时间
    // [self.myView.layer convertTime:CACurrentMediaTime() fromLayer:nil]这个会有点延迟,原因目前还不知道
    CFTimeInterval beginTime = CACurrentMediaTime() - pausedTime;
    //5. 设置动画延迟时间
    /**
        说明:1) 动画在第0秒的时候开始动
             2) 在第5秒的时候暂停了,即anim.timeOffset = 5;
             3) 在第8秒的时候恢复运动,5~8相隔3秒,anim.beginTime属性是延迟多少秒执行,
                这样anim.beginTime = 3; 距上次暂停的时间开始推迟3秒执行,正好是当前时间第8秒
     **/
    [self.myView.layer setBeginTime:beginTime];
}

#pragma mark - CABasic动画
#pragma mark 平移动画到指定点
-(void) translationTo:(CGPoint) location{
    //1. 实例化动画
    // 如果没有指定图层的锚点(定位点)postion默认为UIView的中心点
    CABasicAnimation *anim = [CABasicAnimation animationWithKeyPath:@"position"];
    //2. 设置动画属性
    //1) fromValue(myView的当前坐标) && toValue
    [anim setToValue:[NSValue valueWithCGPoint:location]];
    //2) 动画时长2秒
    [anim setDuration:2.0f];
    //3) 设置代理
    [anim setDelegate:self];
    //4) 让动画停留在目标位置
    /**
     通过设置动画在完成后不删除,以及向前填充,可以做到动画结束后UIView看起来停留在目标位置
     但实质上没有改变UIView的坐标,即frame不会发生变化
     **/
    [anim setRemovedOnCompletion:NO];
    [anim setFillMode:kCAFillModeForwards];
    //5) 要修正动画结束后UIView的坐标点,可以利用setValue方法
    [anim setValue:[NSValue valueWithCGPoint:location] forKeyPath:@"targetPoint"];
    [anim setValue:@"translationTo" forKeyPath:@"animationType"];
    //6) 将动画添加到图层
    // 将动画添加到图层后,系统会按照定义好的属性开始动画,通常程序员不再与动画进行交互
    [self.myView.layer addAnimation:anim forKey:nil];
}

#pragma mark 旋转动画
-(void) rotationAnimation{
    //1. 实例化对象
    // 默认沿着Z轴旋转
    CABasicAnimation *anim = [CABasicAnimation animationWithKeyPath:@"transform.rotation"];
    //2. 设置属性
    //1) fromValue && toValue
    [anim setToValue:@(2 * M_PI)];
    //2) 设置无限循环
    [anim setDuration:2.0f];
    //3) 设置循环次数,无限循环赋值为HUGE_VALF
    [anim setRepeatCount:HUGE_VALF];
    //4) 动画结束后,不要删除图层
    [anim setRemovedOnCompletion:NO];
    //3. 添加到layer
    [self.myView.layer addAnimation:anim forKey:@"rotationAnim"];
}

#pragma mark 缩放动画
-(void) scaleAnimation{
    //1. 实例化动画
    CABasicAnimation *anim = [CABasicAnimation animationWithKeyPath:@"transform.scale"];
    //2. 设置属性
    //1) fromValue && toValue
    //默认为1.0
    //[anim setFromValue:@(1.0)];
    [anim setToValue:@(0.5)];
    //2) 自动还原
    [anim setAutoreverses:YES];
    //3) 设置时长
    [anim setDuration:2.0f];
    //3. 将动画添加到层
    [self.myView.layer addAnimation:anim forKey:nil];
}
@end
#import "AppDelegate.h"
#import "MainViewController.h"

@interface AppDelegate ()
@property (weak,nonatomic) MainViewController *mainController;
@end

@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    self.window.backgroundColor = [UIColor whiteColor];
    MainViewController *controller = [[MainViewController alloc]init];
    self.window.rootViewController = controller;
    self.mainController = controller;
    [self.window makeKeyAndVisible];
    return YES;
}
#pragma mark 失去焦点
- (void)applicationWillResignActive:(UIApplication *)application
{
    NSLog(@"失去焦点");
    [self.mainController pauseAnimation];
}
#pragma mark 进入后台
- (void)applicationDidEnterBackground:(UIApplication *)application
{
    NSLog(@"进入后台");
}
#pragma mark 进入前台
- (void)applicationWillEnterForeground:(UIApplication *)application
{
    NSLog(@"进入前台");
}
#pragma mark 获取焦点
- (void)applicationDidBecomeActive:(UIApplication *)application
{
    NSLog(@"获取焦点");
    [self.mainController resumeAnimation];
}
- (void)applicationWillTerminate:(UIApplication *)application
{
}
@end

5. CAKeyframeAnimation

  1> 关键帧动画(CAKeyframeAnimation),也是CAPropertyAnimation的子类,与CABasicAnimation的区别是:

    1) CABasicAnimation只能从一个数值(fromValue)变到另外一个数值(toValue),而CAKeyframeAnimation可以使用数组(NSArray)保存动画数值。

  2> 属性说明:

    1) values:上述的NSArray对象。里面的元素称为“关键帧”(keyframe)。动画对象会在指定的时间(duration)内,依次显示values数组中的每一个关键帧

    2) path: 可以设置一个CGPathRef、CGMutablePathRef,让图层按照路径轨迹移动。path值对CALayer的anchorPoint和position起作用。如果设置了path,那么values将被忽略

      3) keyTimes:可以为对应的关键帧指定对应的时间点,其取值范围0~1.0。keyTimes中每一个时间值都对应values中的每一个帧。如果没有设置keyTimes,那么values中的每一个帧的时间都是平分的。

  3> CABasicAnimation可以看做只有2个关键帧的CAKeyframeAnimation.

  4> 计算模式(calculationMode)

    4.1> 在关键帧动画中还有一个非常重要的参数,那便是计算模式(calculationMode),主要是针对values中每一个帧内容为一个坐标点的情况,也就是对anchorPointposition进行的动画。

    4.2> 当在平面坐标系中有多个点的时候,???这些点可以是离散的,也可以是直线相连的

    4.3> calculationMode目前提供如下几种模式:

      1) kCAAnimationLinear:默认值,表示当关键帧为坐标点的时候,关键帧之间直接直线相连进行插值计算。

      2) kCAAnimationDiscrete:离散的,不进行插值计算。所有关键帧都逐个依次显示。

      3) kCAAnimationCubic:对于关键帧为坐标点的关键帧进行圆滑曲线相连后进行插值计算,这里的主要目的是使动画运行的更加圆滑

      4) kCAAnimationCubicPaced:看这个名字就知道和kCAAnimationCubic一定有联系,其实就是在kCAAnimation的基础上使得动画运行的更加均匀。指定了该属性,keyTimes以及timingFunctions也将失效。

  【示例 2 - 关键帧动画】

#import <UIKit/UIKit.h>
@interface AnimationView : UIView
#pragma mark -关键帧动画
#pragma mark 摇晃动画
- (void)shakeAnimation;
#pragma mark 贝塞尔曲线,两个控制点
- (void)moveCurveWithDuration:(CFTimeInterval)duration to:(CGPoint)to;
#pragma mark 贝塞尔曲线,一个控制点
- (void)moveQuadCurveWithDuration:(CFTimeInterval)duration to:(CGPoint)to;
#pragma mark 按照矩形路径平移动画
// 移动的矩形是以当前点为矩形的一个顶点,目标点为矩形的对脚顶点
- (void)moveRectWithDuration:(CFTimeInterval)duration to:(CGPoint)to;
#pragma mark 使用随机中心点控制动画平移
-(void) moveWithDuration:(CFTimeInterval)duration to:(CGPoint)to controlPointCount:(NSInteger)count;
#pragma mark 移动到目标点(当前坐标->(0,0)->location)
-(void) transformTo:(CGPoint) location;
@end
#import "AnimationView.h"
@implementation AnimationView
- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        [self setBackgroundColor:[UIColor blueColor]];
    }
    return self;
}

#pragma mark - 私有方法
#pragma mark 随机生成屏幕的上点
-(CGPoint) randomPoint{
    CGFloat width = self.superview.bounds.size.width;
    CGFloat height = self.superview.bounds.size.height;
    CGFloat x = arc4random_uniform(width);
    CGFloat y = arc4random_uniform(height);
    return CGPointMake(x, y);
}

#pragma mark - 关键帧动画
#pragma mark 摇晃动画
// 课下练习动画的暂停和恢复
- (void)shakeAnimation
{
    // 1. 实例化关键帧动画
    CAKeyframeAnimation *anim = [CAKeyframeAnimation animationWithKeyPath:@"transform.rotation"];
    // 晃动
    //    [anim setDuration:0.5f];
    // 1> 角度
    CGFloat angel = M_PI_4 / 12.0;
    [anim setValues:@[@(angel), @(-angel), @(angel)]];
    // 2> 循环晃
    [anim setRepeatCount:HUGE_VALF];
    // 3. 将动画添加到图层
    [self.layer addAnimation:anim forKey:nil];
}

#pragma mark 贝塞尔曲线,两个控制点
- (void)moveCurveWithDuration:(CFTimeInterval)duration to:(CGPoint)to
{
    // 1. 实例化关键帧动画
    CAKeyframeAnimation *anim = [CAKeyframeAnimation animationWithKeyPath:@"position"];
    // 2. 设置路径
    [anim setDuration:duration];
    // 中间的控制点使用屏幕上得随机点
    CGPoint cp1 = [self randomPoint];
    CGPoint cp2 = [self randomPoint];
    CGMutablePathRef path = CGPathCreateMutable();
    // 设置起始点
    CGPathMoveToPoint(path, NULL, self.center.x, self.center.y);
    // 添加带一个控制点的贝塞尔曲线
    CGPathAddCurveToPoint(path, NULL, cp1.x, cp1.y, cp2.x, cp2.y, to.x, to.y);
    [anim setPath:path];
    CGPathRelease(path);
    // 5) 设置键值记录目标位置,以便动画结束后,修正位置
    [anim setValue:@"translationTo" forKey:@"animationType"];
    [anim setValue:[NSValue valueWithCGPoint:to] forKey:@"targetPoint"];
    [anim setDelegate:self];
    // 3. 将动画添加到图层
    [self.layer addAnimation:anim forKey:nil];
}

#pragma mark 贝塞尔曲线,一个控制点
- (void)moveQuadCurveWithDuration:(CFTimeInterval)duration to:(CGPoint)to
{
    // 1. 实例化关键帧动画
    CAKeyframeAnimation *anim = [CAKeyframeAnimation animationWithKeyPath:@"position"];
    // 2. 设置路径
    [anim setDuration:duration];
    // 中间的控制点使用屏幕上得随机点
    CGPoint cp = [self randomPoint];
    CGMutablePathRef path = CGPathCreateMutable();
    // 设置起始点
    CGPathMoveToPoint(path, NULL, self.center.x, self.center.y);
    // 添加带一个控制点的贝塞尔曲线
    CGPathAddQuadCurveToPoint(path, NULL, cp.x, cp.y, to.x, to.y);
    [anim setPath:path];
    CGPathRelease(path);
    // 5) 设置键值记录目标位置,以便动画结束后,修正位置
    [anim setValue:@"translationTo" forKey:@"animationType"];
    [anim setValue:[NSValue valueWithCGPoint:to] forKey:@"targetPoint"];
    [anim setDelegate:self];
    // 3. 将动画添加到图层
    [self.layer addAnimation:anim forKey:nil];
}

#pragma mark 按照矩形路径平移动画
// 移动的矩形是以当前点为矩形的一个顶点,目标点为矩形的对脚顶点
- (void)moveRectWithDuration:(CFTimeInterval)duration to:(CGPoint)to{
    //1. 实例化动画
    CAKeyframeAnimation *anim = [CAKeyframeAnimation animationWithKeyPath:@"position"];
    //2. 设置属性,按照矩形一定,需要使用到路径
    //1) 创建路径
    CGMutablePathRef path = CGPathCreateMutable();
    //2) 矩形起点、宽、高
    CGFloat width = to.x - self.center.x;
    CGFloat height = to.y - self.center.y;
    CGRect rect = CGRectMake(self.center.x, self.center.y, width, height);
    CGPathAddRect(path, NULL, rect);
    //3) 将路径添加到动画
    [anim setPath:path];
    //4) 释放路径
    CGPathRelease(path);
    //3. 将动画添加到层
    [anim setDuration:duration];
    //3. 添加到层
    [self.layer addAnimation:anim forKey:nil];
}

#pragma mark 使用随机中心点控制动画平移
-(void) moveWithDuration:(CFTimeInterval)duration to:(CGPoint)to controlPointCount:(NSInteger)cpCount{
    CAKeyframeAnimation *anim = [CAKeyframeAnimation animationWithKeyPath:@"position"];
    NSMutableArray *array = [NSMutableArray arrayWithCapacity:cpCount + 2];
    [array addObject:[NSValue valueWithCGPoint:self.center]];
    for (int i = 0; i < cpCount; i++) {
        [array addObject:[NSValue valueWithCGPoint:[self randomPoint]]];
    }
    [array addObject:[NSValue valueWithCGPoint:to]];
    [anim setValues:array];
    [anim setDuration:duration];
    [self.layer addAnimation:anim forKey:nil];
}

#pragma mark 移动到目标点(当前坐标->(0,0)->location)
-(void) transformTo:(CGPoint) location{
     //1. 实例化动画
     CAKeyframeAnimation *anim = [CAKeyframeAnimation animationWithKeyPath:@"position"];
     //2. 设置属性
     //1) 设置Values
     NSValue *p1 = [NSValue valueWithCGPoint:self.center];
     NSValue *p2 = [NSValue valueWithCGPoint:CGPointMake(0, 0)];
     NSValue *p3 = [NSValue valueWithCGPoint:location];
     [anim setValues:@[p1,p2,p3]];
     //2) 设置时长
     [anim setDuration:2.0f];
     //3) 设置代理
     [anim setDelegate:self];
     //4) 动画结束后,不要从图层移除
     [anim setRemovedOnCompletion:NO];
     [anim setFillMode:kCAFillModeForwards];
     //5) 设置Value值,用于修正动画结束后UIView的坐标
     [anim setValue:@"transformTo" forKey:@"animationType"];
     [anim setValue:p3 forKey:@"targetPoint"];
     //3. 添加到层
     [self.layer addAnimation:anim forKey:nil];
}
@end
#import <UIKit/UIKit.h>
@interface MainViewController : UIViewController
@end
#import "MainViewController.h"
#import "AnimationView.h"
@interface MainViewController ()
@property (weak,nonatomic) AnimationView *myView;
@end
@implementation MainViewController
- (void)viewDidLoad
{
    [super viewDidLoad];
    AnimationView *myView = [[AnimationView alloc]initWithFrame:CGRectMake(50, 50, 100, 100)];
    [self.view addSubview:myView];
    self.myView = myView;
    UITapGestureRecognizer *tapRecognizer = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(tapAction:)];
    [self.view addGestureRecognizer:tapRecognizer];
}
#pragma mark -动画代理方法
-(void) animationDidStop:(CAAnimation *)anim finished:(BOOL)flag{
    if (anim) {
            NSString *animationType = [anim valueForKey:@"animationType" ];
        if ([animationType isEqualToString:@"transformTo"]) {
            CGPoint targetPoint = [[anim valueForKey:@"targetPoint"]CGPointValue];
            self.myView.center = targetPoint;
        }
    }
    
    NSLog(@"%@",NSStringFromCGPoint(self.myView.center));
}

#pragma mark - 手势识别器
#pragma mark 点击手势识别器
-(void) tapAction:(UITapGestureRecognizer *) recognizer{
    CGPoint location = [recognizer locationInView:self.view];
    //1) 移动到目标点(当前坐标->(0,0)->location)
    //[self.myView transformTo:location];
    //2) 使用随机中心点控制动画平移
    //[self.myView moveWithDuration:5.0f to:location controlPointCount:5];
    //3) 按照矩形路径平移动画
    //[self.myView moveRectWithDuration:2.0f to:location];
    //4) 贝塞尔曲线,一个控制点
    //[self.myView moveQuadCurveWithDuration:2.0f to:location];
    //5) 贝塞尔曲线,两个控制点
    //[self.myView moveCurveWithDuration:2.0f to:location];
    //6) 摇晃动画
    //[self.myView shakeAnimation];
}
@end

6. CAAnimationGroup

  1> 动画组(CAAnimationGroup),是CAAnimation的子类,可以保存一组动画对象,将CAAnimationGroup添加到层后,组中所有动画将并发执行

  2> 属性说明

    1) animations:用来保存一组动画的NSArray

      默认情况下,一组动画对象是同时运行的,也可以设置动画对象的beginTime属性来更改动画的开始时间。

7. 转场动画

posted on 2015-02-20 17:02  雾里寻梦  阅读(371)  评论(0)    收藏  举报

导航