首页 > 其他分享 >IOS动画(Core Animation)总结 (参考多方文章)

IOS动画(Core Animation)总结 (参考多方文章)

时间:2022-12-08 14:04:17浏览次数:77  
标签:Core 效果 动画 SCREEN IOS 50 HEIGHT Animation NSValue


一、简介

​​iOS​​ 动画主要是指Core Animation框架。官方使用文档地址为:​​Core Animation Guide​​​。
Core Animation是IOS和OS X平台上负责图形渲染与动画的基础框架。Core Animation可以作用与动画视图或者其他可视元素,为你完成了动画所需的大部分绘帧工作。你只需要配置少量的动画参数(如开始点的位置和结束点的位置)即可使用Core Animation的动画效果。Core Animation将大部分实际的绘图任务交给了图形硬件来处理,图形硬件会加速图形渲染的速度。这种自动化的图形加速技术让动画拥有更高的帧率并且显示效果更加平滑,不会加重CPU的负担而影响程序的运行速度。

二、Core Animation类图以及常用字段

Core Animation类的继承关系图

IOS动画(Core Animation)总结 (参考多方文章)_ios

常用属性
duration : 动画的持续时间
beginTime : 动画的开始时间
repeatCount : 动画的重复次数
autoreverses : 执行的动画按照原动画返回执行
timingFunction : 控制动画的显示节奏系统提供五种值选择,分别是:

  • kCAMediaTimingFunctionLinear 线性动画
  • kCAMediaTimingFunctionEaseIn 先慢后快(慢进快出)
  • kCAMediaTimingFunctionEaseOut 先块后慢(快进慢出)
  • kCAMediaTimingFunctionEaseInEaseOut 先慢后快再慢
  • kCAMediaTimingFunctionDefault 默认,也属于中间比较快

delegate : 动画代理。能够检测动画的执行和结束。


<code class="hljs objectivec has-numbering"><span class="hljs-class"><span class="hljs-keyword">@interface</span> <span class="hljs-title">NSObject</span> (<span class="hljs-title">CAAnimationDelegate</span>)</span>
- (<span class="hljs-keyword">void</span>)animationDidStart:(CAAnimation *)anim;
- (<span class="hljs-keyword">void</span>)animationDidStop:(CAAnimation *)anim finished:(<span class="hljs-built_in">BOOL</span>)flag;
<span class="hljs-keyword">@end</span></code>


path:关键帧动画中的执行路径
type : 过渡动画的动画类型,系统提供了四种过渡动画。
- kCATransitionFade 渐变效果
- kCATransitionMoveIn 进入覆盖效果
- kCATransitionPush 推出效果
- kCATransitionReveal 揭露离开效果
subtype : 过渡动画的动画方向
- kCATransitionFromRight 从右侧进入
- kCATransitionFromLeft 从左侧进入
- kCATransitionFromTop 从顶部进入
- kCATransitionFromBottom 从底部进入

三、IOS动画的调用方式

第一种:UIView 代码块调用


<code class="hljs avrasm has-numbering">    _demoView<span class="hljs-preprocessor">.frame</span> = CGRectMake(<span class="hljs-number">0</span>, SCREEN_HEIGHT/<span class="hljs-number">2</span>-<span class="hljs-number">50</span>, <span class="hljs-number">50</span>, <span class="hljs-number">50</span>)<span class="hljs-comment">;</span>
[UIView animateWithDuration:<span class="hljs-number">1.0</span>f animations:^{
_demoView<span class="hljs-preprocessor">.frame</span> = CGRectMake(SCREEN_WIDTH, SCREEN_HEIGHT/<span class="hljs-number">2</span>-<span class="hljs-number">50</span>, <span class="hljs-number">50</span>, <span class="hljs-number">50</span>)<span class="hljs-comment">;</span>
} completion:^(BOOL finished) {
_demoView<span class="hljs-preprocessor">.frame</span> = CGRectMake(SCREEN_WIDTH/<span class="hljs-number">2</span>-<span class="hljs-number">25</span>, SCREEN_HEIGHT/<span class="hljs-number">2</span>-<span class="hljs-number">50</span>, <span class="hljs-number">50</span>, <span class="hljs-number">50</span>)<span class="hljs-comment">;</span>
}]<span class="hljs-comment">;</span></code>


第二种:UIView [begin commit]模式

_demoView.frame = CGRectMake(0, SCREEN_HEIGHT/2-50, 50, 50);
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:1.0f];
_demoView.frame = CGRectMake(SCREEN_WIDTH, SCREEN_HEIGHT/2-50, 50, 50);
[UIView commitAnimations];

第三种:使用Core Animation中的类


<code class="hljs avrasm has-numbering">    CABasicAnimation *anima = [CABasicAnimation animationWithKeyPath:@<span class="hljs-string">"position"</span>]<span class="hljs-comment">;</span>
anima<span class="hljs-preprocessor">.fromValue</span> = [NSValue valueWithCGPoint:CGPointMake(<span class="hljs-number">0</span>, SCREEN_HEIGHT/<span class="hljs-number">2</span>-<span class="hljs-number">75</span>)]<span class="hljs-comment">;</span>
anima<span class="hljs-preprocessor">.toValue</span> = [NSValue valueWithCGPoint:CGPointMake(SCREEN_WIDTH, SCREEN_HEIGHT/<span class="hljs-number">2</span>-<span class="hljs-number">75</span>)]<span class="hljs-comment">;</span>
anima<span class="hljs-preprocessor">.duration</span> = <span class="hljs-number">1.0</span>f<span class="hljs-comment">;</span>
[_demoView<span class="hljs-preprocessor">.layer</span> addAnimation:anima forKey:@<span class="hljs-string">"positionAnimation"</span>]<span class="hljs-comment">;</span></code>


四、IOS动画的使用

4.1:基础动画(CABaseAnimation)

重要属性
fromValue
: keyPath对应的初始值

toValue : keyPath对应的结束值


基础动画主要提供了对于CALayer对象中的可变属性进行简单动画的操作。比如:位移、透明度、缩放、旋转、背景色等等。

效果演示:

IOS动画(Core Animation)总结 (参考多方文章)_图形_02


位移动画代码演示:

<code class="hljs avrasm has-numbering">    //使用CABasicAnimation创建基础动画    CABasicAnimation *anima = [CABasicAnimation animationWithKeyPath:@<span class="hljs-string">"position"</span>]<span class="hljs-comment">;</span>
anima<span class="hljs-preprocessor">.fromValue</span> = [NSValue valueWithCGPoint:CGPointMake(<span class="hljs-number">0</span>, SCREEN_HEIGHT/<span class="hljs-number">2</span>-<span class="hljs-number">75</span>)]<span class="hljs-comment">;</span>
anima<span class="hljs-preprocessor">.toValue</span> = [NSValue valueWithCGPoint:CGPointMake(SCREEN_WIDTH, SCREEN_HEIGHT/<span class="hljs-number">2</span>-<span class="hljs-number">75</span>)]<span class="hljs-comment">;</span>
anima<span class="hljs-preprocessor">.duration</span> = <span class="hljs-number">1.0</span>f<span class="hljs-comment">;</span>
//anima<span class="hljs-preprocessor">.fillMode</span> = kCAFillModeForwards<span class="hljs-comment">;</span>
//anima<span class="hljs-preprocessor">.removedOnCompletion</span> = NO<span class="hljs-comment">;</span>
[_demoView<span class="hljs-preprocessor">.layer</span> addAnimation:anima forKey:@<span class="hljs-string">"positionAnimation"</span>]<span class="hljs-comment">;</span></code>


注意点
如果fillMode=kCAFillModeForwards和removedOnComletion=NO,那么在动画执行完毕后,图层会保持显示动画执行后的状态。但在实质上,图层的属性值还是动画执行前的初始值,并没有真正被改变。

4.2:关键帧动画(CAKeyframeAnimation)

CAKeyframeAnimation和CABaseAnimation都属于CAPropertyAnimatin的子类。CABaseAnimation只能从一个数值(fromValue)变换成另一个数值(toValue),而CAKeyframeAnimation则会使用一个NSArray保存一组关键帧。

重要属性
values
: 就是上述的NSArray对象。里面的元素称为”关键帧”(keyframe)。动画对象会在指定的时间(duration)内,依次显示values数组中的每一个关键帧

path : 可以设置一个CGPathRef\CGMutablePathRef,让层跟着路径移动。path只对CALayer的anchorPoint和position起作用。如果你设置了path,那么values将被忽略。

keyTimes : 可以为对应的关键帧指定对应的时间点,其取值范围为0到1.0,keyTimes中的每一个时间值都对应values中的每一帧.当keyTimes没有设置的时候,各个关键帧的时间是平分的。


效果演示:

IOS动画(Core Animation)总结 (参考多方文章)_ios_03


圆形路径动画代码演示:

<code class="hljs avrasm has-numbering">    CAKeyframeAnimation *anima = [CAKeyframeAnimation animationWithKeyPath:@<span class="hljs-string">"position"</span>]<span class="hljs-comment">;</span>    UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(SCREEN_WIDTH/<span class="hljs-number">2</span>-<span class="hljs-number">100</span>, SCREEN_HEIGHT/<span class="hljs-number">2</span>-<span class="hljs-number">100</span>, <span class="hljs-number">200</span>, <span class="hljs-number">200</span>)]<span class="hljs-comment">;</span>    anima<span class="hljs-preprocessor">.path</span> = path<span class="hljs-preprocessor">.CGPath</span><span class="hljs-comment">;</span>
anima<span class="hljs-preprocessor">.duration</span> = <span class="hljs-number">2.0</span>f<span class="hljs-comment">;</span>
[_demoView<span class="hljs-preprocessor">.layer</span> addAnimation:anima forKey:@<span class="hljs-string">"pathAnimation"</span>]<span class="hljs-comment">;</span></code>


说明:CABasicAnimation可看做是最多只有2个关键帧的CAKeyframeAnimation

4.3:组动画(CAAnimationGroup)

CAAnimation的子类,可以保存一组动画对象,将CAAnimationGroup对象加入层后,组中所有动画对象可以同时并发运行。

重要属性
animations
: 用来保存一组动画对象的NSArray

效果演示:

IOS动画(Core Animation)总结 (参考多方文章)_动画_04


组动画代码演示:

<code class="hljs perl has-numbering">    CAKeyframeAnimation <span class="hljs-variable">*anima1</span> = [CAKeyframeAnimation animationWithKeyPath:<span class="hljs-variable">@"</span>position<span class="hljs-string">"];    NSValue <span class="hljs-variable">*value0</span> = [NSValue valueWithCGPoint:CGPointMake(0, SCREEN_HEIGHT/2-50)];    NSValue <span class="hljs-variable">*value1</span> = [NSValue valueWithCGPoint:CGPointMake(SCREEN_WIDTH/3, SCREEN_HEIGHT/2-50)];    NSValue <span class="hljs-variable">*value2</span> = [NSValue valueWithCGPoint:CGPointMake(SCREEN_WIDTH/3, SCREEN_HEIGHT/2+50)];
NSValue <span class="hljs-variable">*value3</span> = [NSValue valueWithCGPoint:CGPointMake(SCREEN_WIDTH<span class="hljs-variable">*2</span>/3, SCREEN_HEIGHT/2+50)];
NSValue <span class="hljs-variable">*value4</span> = [NSValue valueWithCGPoint:CGPointMake(SCREEN_WIDTH<span class="hljs-variable">*2</span>/3, SCREEN_HEIGHT/2-50)];
NSValue <span class="hljs-variable">*value5</span> = [NSValue valueWithCGPoint:CGPointMake(SCREEN_WIDTH, SCREEN_HEIGHT/2-50)];
anima1.values = [NSArray arrayWithObjects:value0,value1,value2,value3,value4,value5, nil];

//缩放动画
CABasicAnimation <span class="hljs-variable">*anima2</span> = [CABasicAnimation animationWithKeyPath:<span class="hljs-variable">@"</span>transform.scale"</span>];
anima2.fromValue = [NSNumber numberWithFloat:<span class="hljs-number">0</span>.<span class="hljs-number">8</span>f];
anima2.toValue = [NSNumber numberWithFloat:<span class="hljs-number">2.0</span>f];

<span class="hljs-regexp">//</span>旋转动画
CABasicAnimation <span class="hljs-variable">*anima3</span> = [CABasicAnimation animationWithKeyPath:<span class="hljs-variable">@"</span>transform.rotation<span class="hljs-string">"];
anima3.toValue = [NSNumber numberWithFloat:M_PI<span class="hljs-variable">*4</span>];

//组动画
CAAnimationGroup <span class="hljs-variable">*groupAnimation</span> = [CAAnimationGroup animation];
groupAnimation.animations = [NSArray arrayWithObjects:anima1,anima2,anima3, nil];
groupAnimation.duration = 4.0f;

[_demoView.layer addAnimation:groupAnimation forKey:<span class="hljs-variable">@"</span>groupAnimation"</span>];</code>


4.4:过渡动画(CATransition)

CAAnimation的子类,用于做过渡动画或者转场动画,能够为层提供移出屏幕和移入屏幕的动画效果。
重要属性
type
:动画过渡类型

Apple 官方的SDK其实只提供了四种过渡效果。
- kCATransitionFade 渐变效果
- kCATransitionMoveIn 进入覆盖效果
- kCATransitionPush 推出效果
- kCATransitionReveal 揭露离开效果
私有API提供了其他很多非常炫的过渡动画,比如@”cube”、@”suckEffect”、@”oglFlip”、 @”rippleEffect”、@”pageCurl”、@”pageUnCurl”、@”cameraIrisHollowOpen”、@”cameraIrisHollowClose”等。
注意点
私有api,不建议开发者们使用。因为苹果公司不提供维护,并且有可能造成你的app审核不通过。

subtype:动画过渡方向

  • kCATransitionFromRight 从右侧进入
  • kCATransitionFromLeft 从左侧进入
  • kCATransitionFromTop 从顶部进入
  • kCATransitionFromBottom 从底部进入

startProgress:动画起点(在整体动画的百分比)
endProgress:动画终点(在整体动画的百分比)

效果演示:

IOS动画(Core Animation)总结 (参考多方文章)_图形_05

4.5:综合案例

4.5.1 : 仿Path菜单效果

效果演示:

IOS动画(Core Animation)总结 (参考多方文章)_ios_06

动画解析:
1、点击红色按钮,红色按钮旋转。(旋转动画)
2、黑色小按钮依次弹出,并且带有旋转效果。(位移动画、旋转动画、组动画)
3、点击黑色小按钮,其他按钮消失,被点击的黑色按钮变大变淡消失。(缩放动画、alpha动画、组动画)
博主的话:代码过多,这里不做演示。文章最后提供代码下载地址。

4.5.2: 仿钉钉菜单效果

效果演示:

IOS动画(Core Animation)总结 (参考多方文章)_ui_07


看上去挺炫的,其实实现很简单,就是位移动画+缩放动画。

4.5.3: 点赞烟花效果动画

效果演示:

IOS动画(Core Animation)总结 (参考多方文章)_ui_08



这里其实只有按钮变大效果使用的缩放动画。烟花效果 使用的是一种比较特殊的动画–粒子动画。

一个粒子系统一般有两部分组成:

1、CAEmitterCell:可以看作是单个粒子的原型(例如,一个单一的粉扑在一团烟雾)。当散发出一个粒子,UIKit根据这个发射粒子和定义的基础上创建一个随机粒子。此原型包括一些属性来控制粒子的图片,颜色,方向,运动,缩放比例和生命周期。

2、CAEmitterLayer:主要控制发射源的位置、尺寸、发射模式、发射源的形状等等。

以上两个类的属性还是比较多的,这里就不细讲了。大家可以google一下,详细的了解吧。

五、总结

任何复杂的动画其实都是由一个个简单的动画组装而成的,只要我们善于分解和组装,我们就能实现出满意的效果。动画其实也不是那么难。

六、下载地址

github下载地址:​​https://github.com/yixiangboy/IOSAnimationDemo​​​ github:​​https://github.com/yixiangboy​


iOS动画效果与上文相互结合:


理论 UIview VS UIlayer

UIView只是CALyer之上的封装,更准确的来说,UIView是CALyer的简版封装,加上事件处理的集合类。 CALayer是QuartzCore库内的类,是iOS上最基本的绘制单元。其次,我们知道iOS平台的Cocoa Touch 是源于OS X平台的Cocoa),是在Cocoa的基础上添加了适用于移动手机设备的手势识别、动画等特性;但从底层实现上来说,Cocoa Touch与Cocoa共用一套底层的库,其中就包括了QuartCore.framework;但QuartCore.framework一开始就是为OS X设计的,所以其中有部分特性是不适合做移动设备开发的,比如最重要的坐标系统。因此,我们也就不难理解为何UIView/NSView在CALayer上做了一层封装。

基于UIView实现的动画

简单的Block动画

IOS动画(Core Animation)总结 (参考多方文章)_动画_09

UIView

IOS动画(Core Animation)总结 (参考多方文章)_动画_10

弹性动画

IOS动画(Core Animation)总结 (参考多方文章)_界面_11

关键帧动画(中间可以添加合适多的帧来做不同的衔接动画)

IOS动画(Core Animation)总结 (参考多方文章)_ios_12

CALayer动画

IOS动画(Core Animation)总结 (参考多方文章)_ui_13

常用属性 

duration : 动画的持续时间

beginTime : 动画的开始时间 

repeatCount : 动画的重复次数 

autoreverses : 执行的动画按照原动画返回执行 

timingFunction : 控制动画的显示节奏,系统提供五种值选择, 分别是 

  • kCAMediaTimingFunctionLinear 线性动画
  • kCAMediaTimingFunctionEaseIn 先慢后快(慢进快出)
  • kCAMediaTimingFunctionEaseOut 先块后慢(快进慢出)
  • kCAMediaTimingFunctionEaseInEaseOut 先慢后快再慢
  • kCAMediaTimingFunctionDefault 默认,也属于中间比较快

path:关键帧动画中的执行路径 

type:过渡动画的动画类型,系统提供了四种过渡动画:

  • kCATransitionFade 渐变效果
  • kCATransitionMoveIn 进入覆盖效果
  • kCATransitionPush 推出效果
  • kCATransitionReveal 揭露离开效果

subtype : 过渡动画的动画方向

  • kCATransitionFromRight 从右侧进入
  • kCATransitionFromLeft 从左侧进入 
  • kCATransitionFromTop 从顶部进入 
  • kCATransitionFromBottom 从底部进入

基础动画主要提供了对于CALayer对象中的可变属性进行简单动画的操作。比如:位移、透明度、缩放、旋转、背景色等等。 重要属性 fromValue : keyPath对应的初始值 toValue : keyPath对应的结束值。

  • 基础动画(CABaseAnimation) 0:1 1:0 实现下拉剪头的展开和收起

IOS动画(Core Animation)总结 (参考多方文章)_ui_14

  • 关键帧动画(CAKeyframeAnimation) CAKeyframeAnimation和CABaseAnimation都属于CAPropertyAnimatin的子类。CABaseAnimation只能从一个数值(fromValue)变换成另一个数值(toValue),而CAKeyframeAnimation则会使用一个NSArray保存一组关键帧。 重要属性 values : 就是上述的NSArray对象。里面的元素称为”关键帧”(keyframe)。动画对象会在指定的时间(duration)内,依次显示values数组中的每一个关键帧 path : 可以设置一个CGPathRefCGMutablePathRef,让层跟着路径移动。path只对CALayer的anchorPoint和position起作用。如果你设置了path,那么values将被忽略。 keyTimes : 可以为对应的关键帧指定对应的时间点,其取值范围为0到1.0,keyTimes中的每一个时间值都对应values中的每一帧.当keyTimes没有设置的时候,各个关键帧的时间是平分的。
  • 组合动画:

IOS动画(Core Animation)总结 (参考多方文章)_ios_15

  • 过渡动画(CATransition) 多数为私有的API使用后无法上架app。 私有API提供了其他很多非常炫的过渡动画,比如@”cube”、@”suckEffect”、@”oglFlip”、 @”rippleEffect”、@”pageCurl”、@”pageUnCurl”、@”cameraIrisHollowOpen”、@”cameraIrisHollowClose”等。

粒子动画

transform动画

transform是一个非常重要的属性,它在矩阵变换的层面上改变视图的显示效果,完成旋转、形变、平移等等操作。在它被修改的同时,视图的frame也会被真实改变。有两个数据类型用来表示transform,分别是CGAffineTransform和CATransform3D。前者作用于UIView,后者为layer层次的变换类型。基于后者可以实现更加强大的功能。 对于想要了解矩阵变换是如何作用实现的,可以参考这篇博客: ​​ CGAffineTransform 放射变换​​

IOS动画(Core Animation)总结 (参考多方文章)_ui_16

在开始使用transform实现你的动画之前,我先介绍几个常用的函数:

IOS动画(Core Animation)总结 (参考多方文章)_ui_17

transform严格的说不是一种动画,而是动画中的一部分操作,我拿出来说是因为它同时出现在了UIView 动画和CALayer动画中。

一些应用

利用上面CALayer 基础动画的代码实现下拉剪头的展开和收起,还可以实现时钟指针的旋转

IOS动画(Core Animation)总结 (参考多方文章)_ui_18

输入框在输入错误信息时的摇晃效果。

IOS动画(Core Animation)总结 (参考多方文章)_动画_19

利用CAShapeLayer 和CABasicAnimation 可以实现加载动画。

IOS动画(Core Animation)总结 (参考多方文章)_ios_20

iOS渲染视图的层级图: 

IOS动画(Core Animation)总结 (参考多方文章)_动画_21



标签:Core,效果,动画,SCREEN,IOS,50,HEIGHT,Animation,NSValue
From: https://blog.51cto.com/u_15894905/5921079

相关文章

  • Axios异步通信
    什么是Axios?Axios是一个开源的可以用在浏览器端和NodeJS的异步通信框架,主要作用就是实现AJAX异步通信,其功能特点如下:··从浏览器中创建XMLHttpRequests··从node......
  • iOS APP打包上传到APPstore的最新步骤​
     一、前言:​作为一名iOS开发者,把辛辛苦苦开发出来的App上传到AppStore是件必要的事。但是很多人还是不知道该怎么上传到AppStore上​下面就来详细讲解一下具体流程步......
  • iOS app上架app store流程详解​
     前提条件​在有效期内的苹果开发者账号(类型为个人或者公司账号)。还有一种情况,就是你的AppleID被添加到公司开发者账号团队里面,这样也是可以的,但是需要叫管理员给你开......
  • iOS APP上架App Store其中一个步骤就是要把ipa文件上传到App Store!​
     下面进行步骤介绍!​利用Appuploader这个软件,可以在Windows、Linux或Mac系统中申请ios和上传IPA到AppStoreConnect。​ 非常的方便,没有Mac也可以用Appuploader在Wi......
  • Angular 复习与进阶系列 – 谈谈 ASP.NET Core & Angular & React 在业务开发上各自的
    前言日常,我的开发都围绕着ASP.NETCore和Angular.这篇想聊聊它们各自的特点和解决问题的方式. 以及最重要的,我们该在什么时候使用何种方案更为妥当.  浅谈......
  • iOS APP打包上传到APPstore的最新步骤​
    一、前言:​作为一名iOS开发者,把辛辛苦苦开发出来的App上传到AppStore是件必要的事。但是很多人还是不知道该怎么上传到AppStore上​下面就来详细讲解一下具体流程步骤。​......
  • iOS AppStore上架流程图文详解​
     1、首先得注册AppleDeveloper的开发者账号,最后如果要上架苹果商店,这个账号是要交年费的,核算下来大概600多元人民币。​2、接下来要登录AppleDeveloper网站,点击“Acco......
  • app提交上架最新流程 ios​
    ​一、上架基本需求资料1、苹果开发者账号(公司已有可以不用申请,需要开通开发者功能,每年99美元)​2、开发好的APP​二、证书上架版本需要使用正式的证书​1、创建证书​​A......
  • iOS AppStore上架流程图文详解​
    1、首先得注册AppleDeveloper的开发者账号,最后如果要上架苹果商店,这个账号是要交年费的,核算下来大概600多元人民币。​2、接下来要登录AppleDeveloper网站,点击“Account”......
  • 未能加载文件或程序集“CefSharp.Core.dll”或它的某一个依赖项
    win10系统或win2012server系统 在使用CefSharp时CefSharp67.00:System.IO.FileNotFoundException:未能加载文件或程序集“CefSharp.Core.dll”或它的某一个依赖项......