iOS CALayer动画

作者: ThinkerH | 来源:发表于2017-03-03 23:26 被阅读420次

隐式动画

  • 什么是隐式动画?

每一个UIView内部都默认有着一个CALayer,称之为Root Layer(根层),而所有的非Root Layer,即手动创建的CALayer对象都默认存在着隐式动画,当对这些手动创建的CALayer的部分属性进行修改时,就会默认产生一些动画效果,而这些属性则称之为可动画属性--Animatable Properties。例如:bounds、backgroundColor、position等都是动画属性。

当然,默认的隐式动画也可以通过CATransaction来关闭:

    
[CATransaction begin];
[CATransaction setDisableActions:YES];
self.myview.layer.position = CGPointMake(10, 10);
[CATransaction commit];

这里CALayer有两个非常重要的属性:


@property CGPoint position;
@property CGPoint anchorPoint;
  • position属性:用来设置CALayer在分层中的位置,以父层的左上角为原点。
  • anchorPoint属性:锚点,是描述CALayer自身的,决定着CALayer上哪个点定位在position属性所在的父层的位置,以自身的左上角为原点,默认为CALayer的中点(0.5,0.5),注意锚点的x、y取值范围为0~1。

隐式动画举例:

  • 效果:
  • 实现代码:
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    [CATransaction begin];
    //设置事务有没有动画
    [CATransaction setDisableActions:NO];
    //设置事务动画的执行时长.
    [CATransaction setAnimationDuration:1];
    
    self.layer.bounds = CGRectMake(0, 0, arc4random_uniform(200), arc4random_uniform(200));
    self.layer.position = CGPointMake(arc4random_uniform(300), arc4random_uniform(400));
    self.layer.backgroundColor = [self randomColor].CGColor;
    self.layer.cornerRadius = arc4random_uniform(50);
    [CATransaction commit];
}

- (UIColor *)randomColor{
    
    CGFloat r = arc4random_uniform(256) /255.0;
    CGFloat g = arc4random_uniform(256) /255.0;
    CGFloat b = arc4random_uniform(256) /255.0;
    
    return [UIColor colorWithRed:r green:g blue:b alpha:1];
}

核心动画

这里主要介绍iOS的几种核心动画。

  • 基本动画
  • 关键帧动画
  • 动画组
  • 转场动画

核心动画(Core Animation)的动画执行过程都是在后台线程操作的,不会阻塞主线程。

动画的继承关系如下图:

核心动画的使用步骤:

  1. 首先要有一个CALayer
  2. 初始化一个CAAnimation对象,设置相关动画属性
  3. 调用CALayer的addAnimation:forKey:方法,将CAAnimation对象添加到CALayer中,开始动画
  4. 调用CALayer的removeAnimationForKey:方法可停止CALayer中的动画

注意:CAAnimation是所有动画对象的父类,负责控制动画的持续时间和速度,是个抽象类,不能直接使用,需使用它的子类。CAAnimation的CAPropertyAnimation子类,也是抽象类,不可直接使用,需使用它的两个子类CABasicAnimation和CAKeyframeAnimation。

使用效果

CABasicAnimation

  • 效果
  • 实现代码:

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{

    CABasicAnimation *anim = [CABasicAnimation animation];
    anim.keyPath = @"position";
    anim.toValue = [NSValue valueWithCGPoint:CGPointMake(200, 400)];
    anim.removedOnCompletion = NO;
    //保存动画最前面效果
    anim.fillMode = kCAFillModeForwards;
    
    [self.redView.layer addAnimation:anim forKey:nil];
    
}

CAKeyframeAnimation

  • 效果:
  • 实现代码:

    CAKeyframeAnimation *anim = [CAKeyframeAnimation animation];
    
    anim.keyPath = @"position";
    
    UIBezierPath *path = [UIBezierPath bezierPath];
    
    [path moveToPoint:CGPointMake(140, 100)];
    
    [path addLineToPoint:CGPointMake(160, 100)];
    
    anim.path = path.CGPath;
    
    anim.repeatCount = MAXFLOAT;
    
    anim.autoreverses = YES;
    
    anim.duration = 1;
    
    [self.iconV.layer addAnimation:anim forKey:nil];

CATransition

  • 效果:
  • 实现代码:

typedef enum : NSUInteger {
    Fade = 1,                   //淡入淡出
    Push,                       //推挤
    Reveal,                     //揭开
    MoveIn,                     //覆盖
    Cube,                       //立方体
    SuckEffect,                 //吮吸
    OglFlip,                    //翻转
    RippleEffect,               //波纹
    PageCurl,                   //翻页
    PageUnCurl,                 //反翻页
    CameraIrisHollowOpen,       //开镜头
    CameraIrisHollowClose,      //关镜头
    CurlDown,                   //下翻页
    CurlUp,                     //上翻页
    FlipFromLeft,               //左翻转
    FlipFromRight,              //右翻转
     
} AnimationType;

- (void)CATransition{
    
    //转场代码必须得要和转场动画在同一个方法当中.
    //创建动画
    CATransition *anim = [CATransition animation];
    
    //设置转场类型
    anim.type = @"pageCurl";
    
    //设置转场的方向
    anim.subtype = kCATransitionFromTop;
    //设置动画的开始点.
    anim.startProgress = 0.2;
    //设置动画的结束点.
    anim.endProgress = 0.8;
    
    anim.duration = 1;
    [self.imageV.layer addAnimation:anim forKey:nil];
      
}

CAAnimationGroup

  • 效果:
  • 实现代码:

-(void)touchesBegan:(nonnull NSSet<UITouch *> *)touches withEvent:(nullable UIEvent *)event{
    
    CAAnimationGroup *group = [CAAnimationGroup animation];
    
    //缩放
    CABasicAnimation *scaleAnim = [CABasicAnimation animation];
    //设置属性
    scaleAnim.keyPath = @"transform.scale";
    scaleAnim.toValue = @0.5;

    
    //平移
    CABasicAnimation *Anim = [CABasicAnimation animation];
    //设置属性
    Anim.keyPath = @"position.y";
    Anim.toValue = @(400);
    group.animations = @[scaleAnim,Anim];
    
    
    group.removedOnCompletion = NO;
    group.fillMode  = kCAFillModeForwards;
    //添加动画
    [self.redView.layer addAnimation:group forKey:nil];
    
}

这里要区分好UIView动画和核心动画的使用场景,核心动画只作用在layer,核心动画修改的值都是假像,它的真实位置没有发生变化。需要交互的用UIView,不需要进行交互时两个都可以使用。

相关文章

网友评论

    本文标题:iOS CALayer动画

    本文链接:https://www.haomeiwen.com/subject/upqdgttx.html