当前位置: 首页 > news >正文

CALayer动画专题

2019独角兽企业重金招聘Python工程师标准>>> hot3.png

CALayer动画专题

来自《ios核心动画高级技巧》书中的一些例子总结,包含了

  • 隐式动画
  • 显式动画
  • 缓冲-动画速度变化函数

https://zsisme.gitbooks.io/ios-/content/chapter7/transactions.html

隐式动画

当你改变CALayer的一个可做动画的属性,它并不能立刻在屏幕上体现出来。相反,它是从先前的值平滑过渡到新的值。这一切都是默认的行为,你不需要做额外的操作。

隐式动画通过改变layer的backgroundColor实现颜色渐变的动画

    //randomize the layer background color
    CGFloat red = arc4random() / (CGFloat)INT_MAX;
    CGFloat green = arc4random() / (CGFloat)INT_MAX;
    CGFloat blue = arc4random() / (CGFloat)INT_MAX;
    self.colorLayer.backgroundColor = [UIColor colorWithRed:red green:green blue:blue alpha:1.0].CGColor;                                                                             ```

#### 隐式动画的事务
`CATransaction` 可以
- 设置动画的时间
- 设置是否开启隐式动画  
- 其他

```objc
    //begin a new transaction
    [CATransaction begin];
    //set the animation duration to 1 second
    [CATransaction setAnimationDuration:1.0];
    //randomize the layer background color
    CGFloat red = arc4random() / (CGFloat)INT_MAX;
    CGFloat green = arc4random() / (CGFloat)INT_MAX;
    CGFloat blue = arc4random() / (CGFloat)INT_MAX;
    self.colorLayer.backgroundColor = [UIColor colorWithRed:red green:green blue:blue alpha:1.0].CGColor;
    //commit the transaction
    [CATransaction commit];

事务的完成block

    //add the spin animation on completion
    [CATransaction setCompletionBlock:^{
        //rotate the layer 90 degrees
        CGAffineTransform transform = self.colorLayer.affineTransform;
        transform = CGAffineTransformRotate(transform, M_PI_2);
        self.colorLayer.affineTransform = transform;
    }];

view关联的layer禁用了隐式动画

默认的view中关联的View禁用了layer的隐式动画,一种简单的方式是设置action来达到隐式动画的效果

    //begin a new transaction
    [CATransaction begin];
    //set the animation duration to 1 second
    [CATransaction setAnimationDuration:1.0];
    //randomize the layer background color
    CGFloat red = arc4random() / (CGFloat)INT_MAX;
    CGFloat green = arc4random() / (CGFloat)INT_MAX;
    CGFloat blue = arc4random() / (CGFloat)INT_MAX;
    self.layerView.layer.backgroundColor = [UIColor colorWithRed:red green:green blue:blue alpha:1.0].CGColor;
    //commit the transaction
    [CATransaction commit];

图层颜色瞬间切换到新的值,而不是之前平滑过渡的动画。

可以设置默认隐式动画的行为,如下设置了关闭隐式动画,在非view关联的layer上也不会有隐式动画的行为了

[CATransaction setDisableActions:YES];

自定义隐式动画的行为

view关联的layer可以通过设置action来实现隐式动画

    //add a custom action
    CATransition *transition = [CATransition animation];
    transition.type = kCATransitionPush;
    transition.subtype = kCATransitionFromLeft;
    self.colorLayer.actions = @{@"backgroundColor": transition};
    //add it to our view
    [self.layerView.layer addSublayer:self.colorLayer];

显式动画

显式的调用 CALayer 的方法 addAnimation 执行动画效果

颜色变换帧动画:

    //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];

路径帧动画:

    //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)];

    //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;
    [shipLayer addAnimation:animation forKey:nil];

旋转动画:

    //animate the ship rotation
    CABasicAnimation *animation = [CABasicAnimation animation];
    animation.keyPath = @"transform.rotation";
    animation.duration = 2.0;
    animation.byValue = @(M_PI * 2);
    [shipLayer addAnimation:animation forKey:nil];

动画组

CAAnimationGroup 可以把这些动画组合在一起。

    //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 a colored layer
    CALayer *colorLayer = [CALayer layer];
    colorLayer.frame = CGRectMake(0, 0, 64, 64);
    colorLayer.position = CGPointMake(0, 150);
    colorLayer.backgroundColor = [UIColor greenColor].CGColor;
    [self.containerView.layer addSublayer:colorLayer];

    //create the position animation
    CAKeyframeAnimation *animation1 = [CAKeyframeAnimation animation];
    animation1.keyPath = @"position";
    animation1.path = bezierPath.CGPath;
    animation1.rotationMode = kCAAnimationRotateAuto;

    //create the color animation
    CABasicAnimation *animation2 = [CABasicAnimation animation];
    animation2.keyPath = @"backgroundColor";
    animation2.toValue = (__bridge id)[UIColor redColor].CGColor;

    //create group animation
    CAAnimationGroup *groupAnimation = [CAAnimationGroup animation];
    groupAnimation.animations = @[animation1, animation2]; 
    groupAnimation.duration = 4.0;

    //add the animation to the color layer
    [colorLayer addAnimation:groupAnimation forKey:nil];

缓冲-动画速度变化函数

动画速度

  • Layer 计时函数:

这里有一些方式来创建CAMediaTimingFunction,最简单的方式是调用+timingFunctionWithName:的构造方法。这里传入如下几个常量之一:

kCAMediaTimingFunctionLinear //先行匀速
kCAMediaTimingFunctionEaseIn //加速
kCAMediaTimingFunctionEaseOut //减速
kCAMediaTimingFunctionEaseInEaseOut //加速然后减速
kCAMediaTimingFunctionDefault //默认行为,和kCAMediaTimingFunctionEaseInEaseOut相似
    //configure the transaction
    [CATransaction begin];
    [CATransaction setAnimationDuration:1.0];
    [CATransaction setAnimationTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut]];
    //set the position
    self.colorLayer.position = [[touches anyObject] locationInView:self.view];
    //commit transaction
    [CATransaction commit];
  • UIView 计时函数

UIKit的动画也同样支持这些缓冲方法的使用,尽管语法和常量有些不同,为了改变UIView动画的缓冲选项,给options参数添加如下常量之一:

UIViewAnimationOptionCurveEaseInOut 
UIViewAnimationOptionCurveEaseIn 
UIViewAnimationOptionCurveEaseOut 
UIViewAnimationOptionCurveLinear

UIView 动画指定计时函数选项

    //perform the animation
    [UIView animateWithDuration:1.0 delay:0.0
                        options:UIViewAnimationOptionCurveEaseOut
                     animations:^{
                            //set the position
                            self.colorView.center = [[touches anyObject] locationInView:self.view];
                        }
                     completion:NULL];

计时函数和关键帧动画

CAKeyframeAnimation有一个NSArray类型的timingFunctions属性,我们可以用它来对每次动画的步骤指定不同的计时函数。但是指定函数的个数一定要等于keyframes数组的元素个数减一,因为它是描述每一帧之间动画速度的函数。

    //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 ];
    //add timing function
    CAMediaTimingFunction *fn = [CAMediaTimingFunction functionWithName: kCAMediaTimingFunctionEaseIn];
    animation.timingFunctions = @[fn, fn, fn];
    //apply animation to layer
    [self.colorLayer addAnimation:animation forKey:nil];

转载于:https://my.oschina.net/FEEDFACF/blog/1618122

相关文章:

  • 虽然看的一知半解,但是感觉有一天用到时会很有用,转
  • B1016. 部分A+B (15)
  • OSGi与第一层语义
  • 如何避免TiddlyWiki变慢
  • 山寨一个 Promise
  • 重写、覆盖、重载、多态几个概念的区别分析
  • Ankara prefabrik evler
  • oracle 简单SQL
  • 快速安装配置zabbix_agent端
  • hdu 1754:I Hate It(线段树,入门题,RMQ问题)
  • Unity加载模块深度解析(Shader篇)
  • Android自带SipDemo详解 4
  • nodejs小问题拾遗
  • 李寒峰:微信支付-无法阻挡的生活潮流
  • 20.34 批量远程执行命令
  • Android 初级面试者拾遗(前台界面篇)之 Activity 和 Fragment
  • in typeof instanceof ===这些运算符有什么作用
  • Java 23种设计模式 之单例模式 7种实现方式
  • Java,console输出实时的转向GUI textbox
  • JSONP原理
  • Python - 闭包Closure
  • react-native 安卓真机环境搭建
  • Terraform入门 - 3. 变更基础设施
  • 看域名解析域名安全对SEO的影响
  • 小程序上传图片到七牛云(支持多张上传,预览,删除)
  • 云栖大讲堂Java基础入门(三)- 阿里巴巴Java开发手册介绍
  • 这几个编码小技巧将令你 PHP 代码更加简洁
  • ​html.parser --- 简单的 HTML 和 XHTML 解析器​
  • #define 用法
  • #每日一题合集#牛客JZ23-JZ33
  • #图像处理
  • $redis-setphp_redis Set命令,php操作Redis Set函数介绍
  • (LeetCode) T14. Longest Common Prefix
  • (M)unity2D敌人的创建、人物属性设置,遇敌掉血
  • (笔试题)分解质因式
  • (第61天)多租户架构(CDB/PDB)
  • (附表设计)不是我吹!超级全面的权限系统设计方案面世了
  • (附源码)springboot美食分享系统 毕业设计 612231
  • (附源码)ssm经济信息门户网站 毕业设计 141634
  • (转)Sql Server 保留几位小数的两种做法
  • .equal()和==的区别 怎样判断字符串为空问题: Illegal invoke-super to void nio.file.AccessDeniedException
  • .net 怎么循环得到数组里的值_关于js数组
  • .Net 转战 Android 4.4 日常笔记(4)--按钮事件和国际化
  • .Net接口调试与案例
  • .NET中的Event与Delegates,从Publisher到Subscriber的衔接!
  • [ 常用工具篇 ] POC-bomber 漏洞检测工具安装及使用详解
  • [202209]mysql8.0 双主集群搭建 亲测可用
  • [ABC294Ex] K-Coloring
  • [Android View] 可绘制形状 (Shape Xml)
  • [Angular] 笔记 8:list/detail 页面以及@Input
  • [C++]STL之map
  • [Deep Learning] 神经网络基础
  • [Flutter]设置应用包名、名称、版本号、最低支持版本、Icon、启动页以及环境判断、平台判断和打包
  • [NAND Flash 7.1] 闪存系统性能优化方向集锦?AC timing? Cache? 多路并发?
  • [NISACTF 2022]join-us