• 动画基础(显式动画)


    CABasicAnimation

    属性动画

    首先我们来探讨一下属性动画。属性动画作用于图层的某个单一属性,并指定了它的一个目标值,或者一连串将要做动画的值。属性动画分为两种:基础和关键帧。

    基础动画

    CABasicAnimation是CAPropertyAnimation的一个子类,CAPropertyAnimation同时也是Core Animation所有动画类型的抽象基类。作为一个抽象类,CAAnimation本身并没有做多少工作,它提供了一个计时函数(见第十章“缓冲”), 一个委托(用于反馈动画状态)以及一个removedOnCompletion,用于标识动画是否该在结束后自动释放(默认YES,为了防止内存泄露)。 CAAnimation同时实现了一些协议,包括CAAction(允许CAAnimation的子类可以提供图层行为),以及 CAMediaTiming

    CAPropertyAnimation通过指定动画的keyPath作用于一个单一属性,CAAnimation通常应用于一个指定的CALayer, 于是这里指的也就是一个图层的keyPath了。实际上它是一个关键路径(一些用点表示法可以在层级关系中指向任意嵌套的对象),而不仅仅是一个属性的名 称,因为这意味着动画不仅可以作用于图层本身的属性,而且还包含了它的子成员的属性,甚至是一些虚拟的属性

    - (void)viewDidLoad
    {
        [super viewDidLoad];
        //create sublayer
        self.colorLayer = [CALayer layer];
        self.colorLayer.frame = CGRectMake(50.0f, 50.0f, 100.0f, 100.0f);
        self.colorLayer.backgroundColor = [UIColor blueColor].CGColor;
        //add it to our view
        [self.view.layer addSublayer:self.colorLayer];
    }
    -(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
    {
        //create a new random color
        CGFloat red = arc4random() / (CGFloat)INT_MAX;
        CGFloat green = arc4random() / (CGFloat)INT_MAX;
        CGFloat blue = arc4random() / (CGFloat)INT_MAX;
        UIColor *color = [UIColor colorWithRed:red green:green blue:blue alpha:1.0];
        //create a basic animation
        CABasicAnimation *animation = [CABasicAnimation animation];
        animation.keyPath = @"backgroundColor";
        animation.toValue = (__bridge id)color.CGColor;
        //apply animation without snap-back
        [self applyBasicAnimation:animation toLayer:self.colorLayer];
    }
    - (void)applyBasicAnimation:(CABasicAnimation *)animation toLayer:(CALayer *)layer
    {
        //set the from value (using presentation layer if available)
        animation.fromValue = [layer.presentationLayer ?: layer valueForKeyPath:animation.keyPath];
        //update the property in advance
        //note: this approach will only work if toValue != nil

        //禁用隐式动画
        [CATransaction begin];
        [CATransaction setDisableActions:YES];
        [layer setValue:animation.toValue forKeyPath:animation.keyPath];
        [CATransaction commit];
        //apply animation to layer
        [layer addAnimation:animation forKey:nil];
    }

    (1)动画代理方法

    - (void)animationDidStop:(CABasicAnimation *)anim finished:(BOOL)flag

    使用注意点:动画本身会作为一个参数传入委托的方法,也许你会认为可以控制器中把动画存储为一个属性,然后在回调用比较,但实际上并不起作用,因为委托传入的动画参数是原始值的一个深拷贝,从而不是同一个值

    CAAnimation实现了KVC(键-值-编码)协议,于是你可以用-setValue:forKey:和-valueForKey:方法来存取属 性。但是CAAnimation有一个不同的性能:它更像一个NSDictionary,可以让你随意设置键值对,即使和你使用的动画类所声明的属性并不 匹配

    [animation setValue:handView forKey:@"handView"];

    可以再委托方法中获取该handView

    UIView *handView = [anim valueForKey:@"handView"];

    CAKeyframeAnimation

    关键帧动画

    CABasicAnimation揭示了大多数隐式动画背后依赖的机制,这的确很有趣,但是显式地给图层添加CABasicAnimation相较于隐式动画而言,只能说费力不讨好。

    CAKeyframeAnimation 是另一种UIKit没有暴露出来但功能强大的类。和CABasicAnimation类似,CAKeyframeAnimation同样是 CAPropertyAnimation的一个子类,它依然作用于单一的一个属性,但是和CABasicAnimation不一样的是,它不限制于设置一 个起始和结束的值,而是可以根据一连串随意的值来做动画

    使用CAKeyframeAnimation应用一系列颜色的变化:

    - (IBAction)changeColor
    {
        //create a keyframe animation
        CAKeyframeAnimation *animation = [CAKeyframeAnimation animation];
        animation.keyPath = @"backgroundColor";
        animation.duration = 2.0;
        animation.values = @[
                             (__bridge id)[UIColor blueColor].CGColor,
                             (__bridge id)[UIColor redColor].CGColor,
                             (__bridge id)[UIColor greenColor].CGColor,
                             (__bridge id)[UIColor blueColor].CGColor ];
        //apply animation to layer
        [self.colorLayer addAnimation:animation forKey:nil];
    }
    注意到序列中开始和结束的颜色都是蓝色,这是因为CAKeyframeAnimation并不能自动把当前值作为第一帧(就像 CABasicAnimation那样把fromValue设为nil)。动画会在开始的时候突然跳转到第一帧的值,然后在动画结束的时候突然恢复到原始 的值。所以为了动画的平滑特性,我们需要开始和结束的关键帧来匹配当前属性的值。
    (1)沿着一个贝塞尔曲线对图层做动画
    @interface ViewController ()
    @property (nonatomic, weak) IBOutlet UIView *containerView;
    @end
    @implementation ViewController
    - (void)viewDidLoad
    {
        [super viewDidLoad];
        //create a path
        UIBezierPath *bezierPath = [[UIBezierPath alloc] init];
        [bezierPath moveToPoint:CGPointMake(0, 150)];
        [bezierPath addCurveToPoint:CGPointMake(300, 150) controlPoint1:CGPointMake(75, 0) controlPoint2:CGPointMake(225, 300)];
        //draw the path using a CAShapeLayer
        CAShapeLayer *pathLayer = [CAShapeLayer layer];
        pathLayer.path = bezierPath.CGPath;
        pathLayer.fillColor = [UIColor clearColor].CGColor;
        pathLayer.strokeColor = [UIColor redColor].CGColor;
        pathLayer.lineWidth = 3.0f;
        [self.containerView.layer addSublayer:pathLayer];
        //add the ship
        CALayer *shipLayer = [CALayer layer];
        shipLayer.frame = CGRectMake(0, 0, 64, 64);
        shipLayer.position = CGPointMake(0, 150);
        shipLayer.contents = (__bridge id)[UIImage imageNamed: @"Ship.png"].CGImage;
        [self.containerView.layer addSublayer:shipLayer];
        //create the keyframe animation
        CAKeyframeAnimation *animation = [CAKeyframeAnimation animation];
        animation.keyPath = @"position";
        animation.duration = 4.0;
        animation.path = bezierPath.CGPath;
           //给CAKeyFrameAnimation添加了一个rotationMode的属性。设置它为常量kCAAnimationRotateAuto(清单8.7),图层将会根据曲线的切线自动旋转
        animation.rotationMode = kCAAnimationRotateAuto;
        [shipLayer addAnimation:animation forKey:nil];
    }
    @end
     
  • 相关阅读:
    [小北De编程手记] : Selenium For C# 教程目录
    [小北De编程手记] [Lesson 02] AutoFramework构建 之 Page Objects
    [小北De编程手记] Lesson 01
    [小北De编程手记] : Lesson 06 玩转 xUnit.Net 之 定义自己的FactAttribute
    [小北De编程手记] : Lesson 05 玩转 xUnit.Net 之 从Assert谈UT框架实践
    [小北De编程手记] : Lesson 04 玩转 xUnit.Net 之 Fixture(下)
    [小北De编程手记] : Lesson 03 玩转 xUnit.Net 之 Fixture(上)
    [小北De编程手记] : Lesson 02 玩转 xUnit.Net 之 基本UnitTest & 数据驱动
    [小北De编程手记] : Lesson 01 玩转 xUnit.Net 之 概述
    [小北De编程手记] : Lesson 08
  • 原文地址:https://www.cnblogs.com/jingdizhiwa/p/5488450.html
Copyright © 2020-2023  润新知