iOS 动画基础

时间:2023-02-24 22:15:49
原文:http://www.cnblogs.com/lujianwenance/p/5733846.html
 
今天说一下有关动画的基础,希望能帮助到一些刚接触iOS动画或者刚开始学习iOS的同学,如有异议,希望能指正,谢谢。  
一、一些基础的概念
     下面介绍的都是QuartzCore框架下的内容。
     1、CAMediaTimingFunction
               时间函数(也被称为缓冲函数),用来描述动画过程中运动的速率情况,也可以看成加速度,apple提供的四种方式:                                     
                    kCAMediaTimingFunctionLinear                  匀速
                    kCAMediaTimingFunctionEaseIn                  慢入
                    kCAMediaTimingFunctionEaseOut                慢出
                    kCAMediaTimingFunctionEaseInEaseOut      慢入慢出
                    kCAMediaTimingFunctionDefault                    默认
               上面的四种情况可以用下图来表示:
               iOS 动画基础
               当然,除了给我们提供的方式,我们还可以自定义时间函数,通过+functionWithControlPoints::::方法。
               这个方式是传入两个点(control point)(前两个是一个点,后两个是一个点)。第一个点与原点形成第一个切线,第二个点与(1,1)点形成另一个切线,
iOS 动画基础
比如说传入的点为(1,0)和(0.75,1),则它的速率(加速度)对应的图形:
                                                                           iOS 动画基础
                  这样就可以自定义你想要的时间函数。
     2、CAMediaTiming
          这是一个protocol,被CALayer和CAAnimation遵守,它是一个分级定时系统,描述一个对象相对于父对象到当地时间的映射(有点绕,这句应该怎么翻译,请大神指教:The CAMediaTiming protocol models a hierarchical timing system, with each object describing the mapping of time values from the object's parent to local time.)。主要是用来描述动画中的开始、执行时间,执行速率,重复次数等。
     3、CFTimeInterval
         表示时间间隔,就是double类型,起的别名
     4、CATransaction
          文档中这样描述的:“Transactions是CoreAnimation批量处理layer-tree去原子的更新渲染的机制,每一个layer tree 的改变都需要transaction这一个部分。CoreAnimation支持两种transactions,“显示”transaction和“隐式”transaction。”显示的transaction是在改变layer tree之前调用[CATransaction begin],然后[CATransaction commit]。隐式的transaction是当没有活跃的transaction的layer tree 在一个线程中被修改时,CoreAnimation自动的创建的transaction,这些transactions在runLoop的下一次迭代中被自动commit,在一些特殊的情况下(比如说没有runLoop或者runLoop被阻塞了),就必须用显示的transaction在合适的时机去渲染layer tree的跟新。”,我相信文档中的描述已经很清晰的说明了CATransaction是干什么,怎么工作的了。下面举一个例子,在例子中进行简单的说明,先看一下效果图:
          iOS 动画基础
 
          这个是一个简单的修改layer的的属性形成的动画,layer的很多属性都是支持隐式动画的,你只需要修改他的属性,它就会自动的加入一个动画的效果。上面的效果,代码如下:
iOS 动画基础
          很简单的代码,只是再点击button的时候修改layer的position和backgroundColor。这属于上面提到的隐式transaction,如果改成显示动画是这样写的,
                                   iOS 动画基础
           可能你会觉得,这样写的结果跟上面的结果一样的,没办法判断到底是不是显示的动画,你可以去掉下面的commit这一行的代码,运行一下,就会发现,并没有执行动画,这就是上面文档中提到的,commit的操作是讲一系列的事务(transactions)提交,等待下个runLoop时渲染。你还可以通过设置CATransaction来修改动画的时间,和之前学习的CAMediaTimingFunction,代码如下:
iOS 动画基础

当然可以使用+(void)setAnimationDuration:(CFTimeInterval)dur;方法来设置动画时间,时间函数也可以。

还有一个关闭隐式动画的方式就是disableAction设置为NO,通过setDisableActions:或者kCATransactionDisableActions都可以。

          CATransaction中还提供有setCompletionBlock或者kCATransactionCompletionBlock,使用上面两种方法可以设置动画之后的的回调,这个应该还是很好用的,很多动画之后是需要进行某一个action的。
     5、CAAction
          这是一个protocol,定义在CALayer的头文件中,CAAnimation和CALayer类遵守了这个协议。它有一个方法,是当一个对象发生一个事件,会调用这个方法,参数为这个事件的name,发生事件的对象anObject,保存这个事件相关的参数dic。
           大家都知道UIView是对CALayer的一层封装,UIView遵守了CALayerDelegate,实现就了协议的方法(具体UIView和CALayer的关系和区别这里就不过多的描述了),到这里就会有一个疑问,为什么CALayer的属性有隐式动画,而UIView的layer没有呢?
           我们先从CALayer的方法actionForKey:方法说起,当我们改变CALayer的属性时,会调用这个方法传递属性名称:
                    1、判断当前delegate对象是否实现了actionForLayer:forKey:方法,如果实现就调用;
                    2、检查这个layer的actions字典中是否有当前属性名称
                    3、在“style”层面检查任何actions字典中是否有当前属性名称
                    4、如果上面所有步骤都没有找到,那么就调用默认的defaultActionForKey:方法
                    注:以上任何一步返回非nil action对象都会被忽略(不做任何操作)
             所以,我们可以自定义一个UIView,然后重写父类的actionForLayer:forKey:方法,返回nil,就可以让一个UIView也有隐式动画了,赶紧试试吧。
              那隐式动画到底是怎样实现的呢?下面我们继续看看CALayer做了什么,我们给自定义的UIView自定义一个Layer,layer中有添加和移除animation的方法,我们在自定义的CALayer重写addAnimation:forKey:方法,当点击button,改变layer的属性时,效果如下图:
iOS 动画基础
iOS 动画基础
从结果看出,隐式动画也是给当前的layer加上了动画效果的。
               下面再做一个实验,刚在自定义的UIView中重写的actionForLayer:forKey方法中直接返回的nil,然后对自定义view的layer做隐式动画的效果是:
iOS 动画基础
iOS 动画基础

可以从中看出,再自定义view中的actionforlayer方法被调用之后就给layer加入了动画。当你在actionForLayer:forKey:方法中加入判断:

iOS 动画基础

这样修改position的隐式动画就没有了,只有对backgroundColor的动画。同时也印证了上面提到的4个步骤。

 6、CAAnimation
          CAAnimation是一个动画的基础类,与他相关的还有CAPropertyAnimation、CAKeyframeAnimation、CABasicAnimation、CASpringAnimation、CATransition和CAAnimationGroup。他们的结构如下图:
iOS 动画基础
          先说CAPropertyAnimation,他是基于property的,他的keyPath就是描述需要动画的属性。additive这个属性是,当被设置为true时说明这个值会被追加的当前layer的这个property的value上,产生一个新的value,当然如果为NO,就相当于给property一个新值。cumulative这个属性,从文档中可以看出有重复次数时才有用,这个属性设为true时这个动画的当前value就是上次动画的结尾的value加上当前重复中的value,如果为false,value就一直是这个值。valueFunction这个是用来转化你设置的动画值为动画需要的矩阵值,不赋值他就有默认的转化方式。
          CABasicAnimation,为一个layer的属性提供基本的单个关键帧动画的能力,使用animationWithKeyPath:来初始化,他的三个属性,fromValue、byValue、toValue,至少有一个值不为nil。
    CAKeyframeAnimation,关键帧动画,values   path keyTimes timintFunctions 这些属性就不多说了,下面主要提一下其他的,calculationMode,计算模式,图形学中的差值计算,这里api中提供了几种模式:
kCAAnimationLinear  默认值,会根据给定的values中的每一个关键帧值之间直线相连进行差值计算
kCAAnimationDiscrete  不进行差值计算,离散的,只是将value中的关键帧一次展示(可以理解成没有过度的动画)
kCAAnimationPaced  keyTimes和timingFunctions设置无效,动画匀速执行,平均分配时间
kCAAnimationCubic  
kCAAnimationCubicPaced  在cubic的基础上匀速动画
 
下面专门说一下kCAAnimationCubic,calculationMode的默认值是每个关键帧之间的直线相连进行插值计算,kCAAnimationCubic是圆滑曲线相连进行差值计算,具体曲线的样子由tensionValues、continuityValues和biasValues三个数组的value来计算,如下图:
iOS 动画基础
     t     切线向量的长度     张力值
     b     切线向量的方向     斜率
     c    切线之间变化的锐度      连续性
想了解详细的数学公式请查看:https://en.wikipedia.org/wiki/Kochanek–Bartels_spline
          rotationMode属性是控制匹配路径的切线,默认为nil,还可以设置kCAAnimationRotateAuto和kCAAnimationRotateAutoReverse。
 
          CASpringAnimation,iOS9加入的新的弹簧模型动画类,简单的介绍一下它的属性,mass对象的质量,质量越大压缩和拉伸的幅度越大,默认值1;stiffness弹簧的刚性,刚性越大产生的动力越大,默认值100;damping阻尼系数,系数越大阻力越大,默认值10;initialVelocity初始速率,默认值0,为正和运动方向一致,为负和运动方向相反;settlingDuration结算时间,返回弹簧动画停止的估算时间,通常用来设置动画的执行时长。
 
 

iOS 动画基础的更多相关文章

  1. iOS 动画基础总结篇

    iOS 动画基础总结篇   动画的大体分类(个人总结可能有误) 分类.png UIView 动画 属性动画 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 1 ...

  2. iOS 动画基础-显式动画

    摘要 显式动画 属性动画 CABasicAnimation *animation = [CABasicAnimation animation];         [self updateHandsAn ...

  3. iOS动画1 — UIView动画

    iOS动画基础是Core Animation核心动画.Core Animation是iOS平台上负责图形渲染与动画的基础设施.由于核心动画的实现比较复杂,苹果提供了实现简单动画的接口—UIView动画 ...

  4. iOS开发UI篇—核心动画(基础动画)

    转自:http://www.cnblogs.com/wendingding/p/3801157.html 文顶顶 最怕你一生碌碌无为 还安慰自己平凡可贵 iOS开发UI篇—核心动画(基础动画) iOS ...

  5. IOS开发基础知识碎片-导航

    1:IOS开发基础知识--碎片1 a:NSString与NSInteger的互换 b:Objective-c中集合里面不能存放基础类型,比如int string float等,只能把它们转化成对象才可 ...

  6. iOS系列 基础篇 05 视图鼻祖 - UIView

    iOS系列 基础篇 05 视图鼻祖 - UIView 目录: UIView“家族” 应用界面的构建层次 视图分类 最后 在Cocoa和Cocoa Touch框架中,“根”类时NSObject类.同样, ...

  7. IOS动画总结

    IOS动画总结   一.基本方式:使用UIView类的UIViewAnimation扩展 + (void)beginAnimations:(NSString *)animationID context ...

  8. IOS 动画专题 --iOS核心动画

    iOS开发系列--让你的应用“动”起来 --iOS核心动画 概览 通过核心动画创建基础动画.关键帧动画.动画组.转场动画,如何通过UIView的装饰方法对这些动画操作进行简化等.在今天的文章里您可以看 ...

  9. ios 动画学习的套路 (二)

    有它们俩你就够了! 说明:下面有些概念我说的不怎么详细,网上实在是太多了,说了我觉得也意义不大了!但链接都给大家了,可以自己去看,重点梳理学习写动画的一个过程和一些好的博客! (一) 说说这两个三方库 ...

随机推荐

  1. spring boot实战(第十三篇)自动配置原理分析

    前言 spring Boot中引入了自动配置,让开发者利用起来更加的简便.快捷,本篇讲利用RabbitMQ的自动配置为例讲分析下Spring Boot中的自动配置原理. 在上一篇末尾讲述了Spring ...

  2. asp.net 页面 输出之前修改 html(render)

    protected override void Render(HtmlTextWriter writer) { StringWriter output = new StringWriter(); ba ...

  3. panguan(判官):一个自研的任务执行引擎的工程实践

    来某厂接近半年了,几乎没写过C++代码,说实话还真的有点手生.最近刚好有一个需求,然而我感觉我也没有办法用C++以外的语言去实现它.于是还是花了几天时间用C++完成编码,这是一个简单的任务执行引擎,它 ...

  4. 【OpenGL】画立方体

    编写一个程序,该程序运行时可以用鼠标的一个按键调整立方体的方向,用另一个按键平移立方体,用第三个按键缩放立方体. 这是题目,我的程序不一定完全按照这个来.初学OpenGL,对那一堆坐标系表示十分混乱, ...

  5. 读取group by 之外的字段

    序号 姓名 性别 身高 1 张三 男  185 2 李四 女  161 3 王五 女  166 4 赵六 男  178 1.获取男生女生人数 select count(性别) , 性别 from 表名 ...

  6. yum 安装 5.6

    http://www.cnblogs.com/XBlack/p/5178758.html

  7. [转载] java垃圾回收机制

    转载自http://blog.csdn.net/randyjiawenjie/article/details/7551228 http://www.daniel-journey.com/archive ...

  8. UNIX网络编程——epoll 系列函数简介、与select、poll 的区别

    前面博客<<UNIX环境高级编程--epoll函数使用详解>>有关于epoll函数的讲解. 一.epoll 系列函数简介 #include <sys/epoll.h&gt ...

  9. rocketmq消息重复推送的问题

    最近,在公司的测试环境,遇到个问题,每次重启应用重启后,原来消费过的消息又被重复推送了一遍,消费者和生产者代码如下: package com.tf56.queue.client; import jav ...

  10. openlayers5实战--踩坑总结

    1.接口返回圆心坐标和半径,直接通过new Circle(center,radius)添加圆形feature变小问题. 解决办法: new  Feature()的geometry参数不能直接赋值new ...