动画

一、Core Animation简介

(1)Core Animation,中文翻译为核心动画,它是一组非常强大的动画处理API,使用它能做出非常炫丽的动画效果
(2)Core Animation的动画执行过程都是在后台操作的,不会阻塞主线程。
(3)Core Animation是直接作用在CALayer上的,并非UIView。

二、Core Animation的使用步骤

1.使用它需要先添加QuartzCore.framework框架和引人主头文件
2.初始化一个CAAnimation对象,并设置一些动画相关属性
3.通过调用CALayer的addAnimation:forKey:方法增加CAAnimation对象到CALayer中,这样就能开始执行动画了
4.通过调用CALayer的removeAnimationForKey:方法可以停止CALayer中的动画

1.过渡动画(转场动画)

CATransition
(1)视图切换
(2)控制器切换

实例:
 //创建一个转场动画
    CATransition *transition = [CATransition animation];
    //设置动画时间
    transition.duration = 1;
    //动画类型
    /*
     CATransition中type的值:
     1     fade = 1,                   //淡入淡出
     2     push,                       //推挤
     3     reveal,                     //揭开
     4     moveIn,                     //覆盖
     5     cube,                       //立方体
     6     suckEffect,                 //吮吸
     7     oglFlip,                    //翻转
     8     rippleEffect,               //波纹
     9     pageCurl,                   //翻页
     10     pageUnCurl,                 //反翻页
     11     cameraIrisHollowOpen,       //开镜头
     12     cameraIrisHollowClose,      //关镜头
     */
    transition.type = @"pageCurl";

      //动画方向
    transition.subtype = kCATransitionFromLeft;

    //执行动画
    [self.imageView.layer addAnimation:transition forKey:nil];

2.关键帧动画

CAKeyframeAnimation

实例
//关键帧动画
    CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:@"position"];
    //动画时间
    animation.duration = 5;
    //设置关键点
    animation.values = @[
                         [NSValue valueWithCGPoint:CGPointMake(130, 130)],
                         [NSValue valueWithCGPoint:CGPointMake(300, 500)],
                         [NSValue valueWithCGPoint:CGPointMake(300, 40)],
                         [NSValue valueWithCGPoint:CGPointMake(30, 40)]
                         ];
    
    //设置运行的速率
    /*
     *  kCAMediaTimingFunctionLinear            线性,即匀速
                            *  kCAMediaTimingFunctionEaseIn            先慢后快
                            *  kCAMediaTimingFunctionEaseOut           先快后慢
                            *  kCAMediaTimingFunctionEaseInEaseOut     先慢后快再慢
                            *  kCAMediaTimingFunctionDefault           实际效果是动画中间比较快.
     */
    animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
    
    //原路返回
    //animation.autoreverses = YES;
    
    //动画次数
    animation.repeatCount = 1;
    
    //停留在终点
    animation.removedOnCompletion = NO;
    animation.fillMode = kCAFillModeForwards;
    
    //执行动画
    [redLayer addAnimation:animation forKey:nil];
构造路径、矩形、圆弧/圆心、线段、带有圆角的矩形、椭圆
//路径
    CGMutablePathRef path = CGPathCreateMutable();
#if 0
    //矩形
    CGPathAddRect(path, NULL, CGRectMake(30, 50, 300, 300));
    //圆弧,圆心(200,200) 半径100 开始弧度0  结束M_PI, true表示逆时针
    CGPathAddArc(path, NULL, 200, 200, 100, 0, M_PI, false);
     //线段
    CGPoint point[3] = {CGPointMake(30, 30),CGPointMake(300, 300),CGPointMake(300, 30),};
    CGPathAddLines(path, NULL, point, sizeof(point)/sizeof(point[0]));
    //带有圆角的矩形
    CGPathAddRoundedRect(path, NULL, CGRectMake(30, 50, 300, 300), 100, 100);
#endif
    
    //椭圆
    CGPathAddEllipseInRect(path, NULL, CGRectMake(30, 40, 300, 500));
    
    //构造贝塞尔曲线
   // CGPathAddCurveToPoint(<#CGMutablePathRef  _Nullable path#>, <#const CGAffineTransform * _Nullable m#>, <#CGFloat cp1x#>, <#CGFloat cp1y#>, <#CGFloat cp2x#>, <#CGFloat cp2y#>, <#CGFloat x#>, <#CGFloat y#>)
    
    
    CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:@"position"];
    //动画时间
    animation.duration = 3;
    //设置动画路径
    animation.path = path;
    //设置动画重复次数
    animation.repeatCount = MAXFLOAT;
    //执行动画
    [redLayer addAnimation:animation forKey:nil];
    
    //移除动画
    //[redLayer removeAnimationForKey:<#(nonnull NSString *)#>];
    
    CGPathRelease(path);

(1)values
(2)path(加入购物车)
(3)输入框输入错误动画

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:@"position.x"];
    animation.duration = 0.15;
    //关键点
    animation.values = @[@(10),@(0),@(-10),@(0)];
    
    //相对于当前的坐标为参考,也就是在当前的位置基础上移动了多少
    animation.additive = YES;
    //动画次数
    animation.repeatCount = 2;
    [self.textField.layer addAnimation:animation forKey:nil];
    
}

(4)视图抖动效果(系统桌面图标删除效果)

//角度转化为弧度
#define kToDian(angle) (M_PI/180 * (angle))
//长按
- (void)handleLongPress:(UILongPressGestureRecognizer *)longPress
{
    if (longPress.state == UIGestureRecognizerStateBegan)
    {
        CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:@"transform.rotation.z"];
        animation.values = @[@(kToDian(5)),@(kToDian(0)),@(kToDian(-5)),@(kToDian(0))];
        animation.duration = 0.2;
        animation.repeatCount = MAXFLOAT;
        //执行动画
        [longPress.view.layer addAnimation:animation forKey:@"animaiton"];
        
        //3秒停止动画
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
            //停止动画 - 移除指定动画
            [longPress.view.layer removeAnimationForKey:@"animaiton"];
            //移除所有动画
            //[longPress.view.layer removeAllAnimations];
        });
    }
}

(5)点赞动画

calculationMode 是控制关键帧动画时间的另一种方法。我们通过将其设置为 kCAAnimationPaced,让 Core Animation 向被驱动的对象施加一个恒定速度,不管路径的各个线段有多长。

additive 属性为 YES 能够对所有形式的需要更新的元素重用相同的动画,且无需提前知道它们的位置。

3.隐式动画

CABasicAnimation
(1)旋转

//隐式动画
    CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"];
    animation.duration = 1;
    //结束的位置
    animation.toValue = @(M_PI * 2);
    //
    animation.repeatCount = MAXFLOAT;
    [imageView.layer addAnimation:animation forKey:nil];

(2)摇一摇(微信摇一摇)

//启动摇一摇
    [UIApplication sharedApplication].applicationSupportsShakeToEdit = YES;

/**
 *  摇一摇开始会触发
 *
 *  @param motion <#motion description#>
 *  @param event  <#event description#>
 */
- (void)motionBegan:(UIEventSubtype)motion withEvent:(UIEvent *)event
{
    NSString *path = [[NSBundle mainBundle] pathForResource:@"shake_sound_male.wav" ofType:nil];
    
    //1.播放音频
    _player = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:path] error:nil];
    //播放音频
    [_player play];
    
    //2.动画
    CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"transform.translation.y"];
    animation.duration = 0.5;
    //原路返回
    animation.autoreverses = YES;
    //向上移动25
    animation.toValue = @(-25);
    [self.topImageView.layer addAnimation:animation forKey:nil];
    
    //下面的图片向下移动 25
    animation.toValue = @(25);
    [self.bottomImageView.layer addAnimation:animation forKey:nil];
    
    
    //TODO::请求数据
}
byValue和toValue的区别,前者是在当前的位置上增加多少,后者是到指定的位置。

4.CAAnimationGroup 动画组

变色变形效果例子

 /*
     1.背景颜色动画
     */
    CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"backgroundColor"];
    //动画时间
    animation.duration = 3;
    //动画起始状态
    animation.fromValue = (__bridge id _Nullable)([UIColor redColor].CGColor);
    //动画终点状态
    animation.toValue = (__bridge id _Nullable)([UIColor greenColor].CGColor);
    animation.autoreverses = YES;
    animation.repeatCount = MAXFLOAT;
    //执行动画
    [layer addAnimation:animation forKey:nil];
    
    /*
     2.圆角半径动画
     */
    CABasicAnimation *cornerRadiusAnimation = [CABasicAnimation animationWithKeyPath:@"cornerRadius"];
    //动画时间
    cornerRadiusAnimation.duration = 3;
    //动画起始状态
    cornerRadiusAnimation.fromValue = @(0);
    //动画终点状态
    cornerRadiusAnimation.toValue = @(100);
    cornerRadiusAnimation.autoreverses = YES;
    cornerRadiusAnimation.repeatCount = MAXFLOAT;
    //执行动画
    [layer addAnimation:cornerRadiusAnimation forKey:nil];

仿真动画

/**
 *  重力行为
 */
@property (nonatomic, strong) UIGravityBehavior *gravity;

/**
 *  碰撞行为
 */
@property (nonatomic, strong) UICollisionBehavior *collision;

/**
 *  仿真行为的执行者
 */
@property (nonatomic, strong) UIDynamicAnimator *animator;
/**
 *  仿真行为的执行者
 */
- (UIDynamicAnimator *)animator
{
    if (!_animator)
    {
        _animator = [[UIDynamicAnimator alloc] initWithReferenceView:self.view];
    }
    
    return _animator;
}

/**
 *  重力行为
 *
 *  @return <#return value description#>
 */
- (UIGravityBehavior *)gravity
{
    if (!_gravity)
    {
        _gravity = [[UIGravityBehavior alloc] init];
    }
    
    return _gravity;
}

/**
 *  碰撞行为
 */
- (UICollisionBehavior *)collision
{
    if (!_collision)
    {
        _collision = [[UICollisionBehavior alloc] init];
        //设置边沿
        _collision.translatesReferenceBoundsIntoBoundary = YES;
    }
    
    return _collision;
}
- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    
   
    
    
    [NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(createItem) userInfo:nil repeats:YES];
    
}

/**
 *  创建仿真对象,并在添加重力和碰撞行为,然后执行
 */
- (void)createItem
{
    /*
     仿真行为:
     1、要有仿真元素。一般是UIView。
     2.仿真行为。
     3.仿真行为执行者。
     */
    
    //仿真元素
    UIView *view = [[UIView alloc] initWithFrame:CGRectMake(arc4random_uniform(self.view.frame.size.width) - 40, 40, 40, 40)];
    view.backgroundColor = [UIColor colorWithRed:arc4random_uniform(256)/255.0 green:arc4random_uniform(256)/255.0 blue:arc4random_uniform(256)/255.0 alpha:1.0];
    [self.view addSubview:view];
    
    
    //添加重力行为
    [self.gravity addItem:view];
    //添加碰撞行为
    [self.collision addItem:view];
    
    //执行重力行为
    [self.animator addBehavior:self.gravity];
    //执行碰撞行为
    [self.animator addBehavior:self.collision];
}

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