iOS动画(一):拍电影与CABasicAnimation

2023-12-14 14:38

本文主要是介绍iOS动画(一):拍电影与CABasicAnimation,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

声明:本文是 编程小翁 原创,转载请注明。
动效设计一直是iOS平台的优势,良好的动效设计可以很好地提升用户体验。而动画则是动效的基础支撑。本动画系列将从易到难逐步分析,本文就是第一站:CABasicAnimation。
通过本文,你能收获到:

以拍电影的思路写动画代码
编写自己的简单动画库
一、概念
这个部分你需要了解以下概念: CALayer、CAAnimation、拍电影(R U kidding me?)

1、CALayer
CALayer是个与UIView很类似的概念,同样有backgroundColor、frame等相似的属性,我们可以将UIView看做一种特殊的CALayer。但实际上UIView是对CALayer封装,在CALayer的基础上再添加交互功能。UIView的显示必须依赖于CALayer。
我们同样可以跟新建view一样新建一个layer,然后添加到某个已有的layer上,同样可以对layer调整大小、位置、透明度等。
一般来说,layer可以有两种用途:一是对view相关属性的设置,包括圆角、阴影、边框等参数,更详细的参数请点击这里;二是实现对view的动画操控。因此对一个view进行动画,本质上是对该view的.layer进行动画操纵。

2、CAAnimation
在iOS中Core Animation层的动画是依赖CAAnimation类实现的。这里提到一个概念,那就是Core Animation层动画。没错,既然有所谓的Core Animation层动画那就应该有其他层动画。看下面的图:

这里写图片描述

在iOS的不同图形层次中都可以写动画代码。越上层,封装程度越高,动画实现越简洁越简单,但是自由度越低;反之亦然。本系列着重介绍Core Animation层的基本动画实现方案。
CAAnimation可以分为以下几类:

CABasicAnimation
基础动画,通过设定起始点,终点,时间,动画会沿着你这设定点进行移动。可以看做特殊的CAKeyFrameAnimation
CAKeyframeAnimation
关键帧动画,可定制度比CABasicAnimation高,也是本系列的接下来的内容
CAAnimationGroup
组动画,支持多个CABasicAnimation或者CAKeyframeAnimation动画同时执行

本文作为系列的第一篇文章,先从最简单的CABasicAnimation说起。

3、拍电影
此刻你心里估计在想:What the f**k? 但其实实现CABasicAnimation动画的过程与拍电影的流程非常类似:

准备演员—>CALayer,规定电影的主角是谁
准备剧本—>CAAnimation,规定电影该怎么演,怎么走,怎么变换
开拍—>AddAnimation,开始执行
唯一的不同估计是电影里演员很重要,颜值担当那是必须的,只要颜值够高,狗血剧本也很受欢迎。但对于基础动画,演员没太大作用,关键是剧本要好要硬。也就是CABasicAnimation要足够精彩。
不扯淡了,进入下一部分。

二、开始拍电影
按照上面的解释,要想实现一个类似图2中蓝色方块的心跳效果就需要这么做:

step1: 准备演员(CALayer初始化)

CALayer *scaleLayer = [[CALayer alloc] init];scaleLayer.backgroundColor = [UIColor blueColor].CGColor;scaleLayer.frame = CGRectMake(60, 20 + kYOffset, 50, 50);scaleLayer.cornerRadius = 10;[self.view.layer addSublayer:scaleLayer];[scaleLayer release];//MRC下

step2: 准备剧本(配置CABasicAnimation)

//设定剧本CABasicAnimation *scaleAnimation = [CABasicAnimation animationWithKeyPath:@"transform.scale”];//keyPath不能填错,有特定被选值scaleAnimation.fromValue = [NSNumber numberWithFloat:1.0];scaleAnimation.toValue = [NSNumber numberWithFloat:1.5];scaleAnimation.autoreverses = YES;scaleAnimation.fillMode = kCAFillModeForwards;scaleAnimation.removedOnCompletion = NO;scaleAnimation.repeatCount = MAXFLOAT;scaleAnimation.duration = 0.8;

step3: 开演

 [scaleLayer addAnimation:scaleAnimation forKey:@"scaleAnimation”];

这里写图片描述

代码中有几个参数需要解释一下:

keyPath: 决定基础动画的类型,该值不能随便取,一旦取错就达不到想要的效果。要改变位置就取position,要改变透明度就取opacity,要等比例缩放就取transform.scale…更多key请看下面的表1,要尽量能记住这些内容
fromValue: 动画的起始状态值,虽然iOS文档给出的类型是id,不过这里应该传NSValue对象,比如NSNumber(NSNubmer继承自NSValue)。其具体含义
autoreverse: 当动画执行到toValue指定的状态时是从toValue的状态逆回去,还是直接跳到fromValue的状态再执行一遍
fileMode: fillMode的作用就是决定当前对象过了非active时间段的行为. 非active时间段是指动画开始之前以及动画结束之后。如果是一个动画CAAnimation,则需要将其removedOnCompletion设置为NO,要不然fillMode不起作用. 下面来讲各个fillMode的意义:

kCAFillModeRemoved 这个是默认值,也就是说当动画开始前和动画结束后,动画对layer都没有影响,动画结束后,layer会恢复到之前的状态
kCAFillModeForwards 当动画结束后,layer会一直保持着动画最后的状态
kCAFillModeBackwards 这个和kCAFillModeForwards是相对的,就是在动画开始前,你只要将动画加入了一个layer,layer便立即进入动画的初始状态。因为有可能出现fromValue不是目前layer的初始状态的情况,如果fromValue就是layer当前的状态,则这个参数就没太大意义。
kCAFillModeBoth 理解了上面两个,这个就很好理解了,这个其实就是上面两个的合成.动画加入后开始之前,layer便处于动画初始状态,动画结束后layer保持动画最后的状态.

这里写图片描述

接下来我们来看一下怎么实现多个动画同时执行,这里会用到上面提到的CAAnimationGroup类。我们的目标是实现图2中最底下的紫色方块的动画,缩放、移动、旋转同时进行。
这时候你可以再回想一下拍电影的过程:

演员,CALayer对象
剧本,这时候就需要准备CAAnimationGroup来当剧本了,剧本由诸如缩放、移动等小剧本合成。
开演,addAnimation
直接看剧本的代码:
缩放:

CABasicAnimation *scaleAnimation = [CABasicAnimation animationWithKeyPath:@"transform.scale"];scaleAnimation.fromValue = [NSNumber numberWithFloat:1.0];scaleAnimation.toValue = [NSNumber numberWithFloat:1.5];scaleAnimation.autoreverses = YES;scaleAnimation.repeatCount = MAXFLOAT;scaleAnimation.duration = 0.8;

移动

CABasicAnimation *moveAnimation = [CABasicAnimation animationWithKeyPath:@"position"];moveAnimation.fromValue = [NSValue valueWithCGPoint:groupLayer.position];moveAnimation.toValue = [NSValue valueWithCGPoint:CGPointMake(320 - 80, groupLayer.position.y)];moveAnimation.autoreverses = YES;moveAnimation.repeatCount = MAXFLOAT;moveAnimation.duration = 2;

旋转

CABasicAnimation *rotateAnimation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.x"];rotateAnimation.fromValue = [NSNumber numberWithFloat:0.0];rotateAnimation.toValue = [NSNumber numberWithFloat:6.0 * M_PI];rotateAnimation.autoreverses = YES;rotateAnimation.repeatCount = MAXFLOAT;rotateAnimation.duration = 2;

你也注意到了,你可以认为其实每个小剧本都是独立的,他们之间唯一的联系就是一起被放到GroupAnimation中:

CAAnimationGroup *groupAnnimation = [CAAnimationGroup animation];groupAnnimation.duration = 2;groupAnnimation.autoreverses = YES;groupAnnimation.animations = @[moveAnimation, scaleAnimation, rotateAnimation];groupAnnimation.repeatCount = MAXFLOAT;

最后把整合后的大剧本groupAnimation交给导演开拍:

[groupLayer addAnimation:groupAnnimation forKey:@"groupAnnimation”];

三、编写自己的动画库
从第二节我们知道,实现基本动画最重要的要有一个CABasicAnimation。于是乎,我们可以用一个工具类或者类扩展提前写好一些动画类型(剧本),返回值是CABasicAnimation对象。每想到一种新的动画类型就可以往里面加,逐渐形成自己动画代码库。比如这样:
这里写图片描述

要用的时候直接取来用:
这里写图片描述

以上代码取自我的一份开源的角标库一句话实现badge效果,动画库文件是CAAnimation+WAnimation.h,欢迎star哦。

四、The End
以上就是CABasicAnimation基本动画的全部内容了,以拍电影的思路去写代码,再记住一些keypath以及annimation的属性含义,你就可以实现自己的炫酷基础动画!

欢迎留言,如果写的不对的地方还请不吝指出。

编程小翁(简书作者)
原文链接:http://www.jianshu.com/p/cd1bc0e82f4d
著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”。

这篇关于iOS动画(一):拍电影与CABasicAnimation的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/492917

相关文章

最好用的WPF加载动画功能

《最好用的WPF加载动画功能》当开发应用程序时,提供良好的用户体验(UX)是至关重要的,加载动画作为一种有效的沟通工具,它不仅能告知用户系统正在工作,还能够通过视觉上的吸引力来增强整体用户体验,本文给... 目录前言需求分析高级用法综合案例总结最后前言当开发应用程序时,提供良好的用户体验(UX)是至关重要

基于Python实现PDF动画翻页效果的阅读器

《基于Python实现PDF动画翻页效果的阅读器》在这篇博客中,我们将深入分析一个基于wxPython实现的PDF阅读器程序,该程序支持加载PDF文件并显示页面内容,同时支持页面切换动画效果,文中有详... 目录全部代码代码结构初始化 UI 界面加载 PDF 文件显示 PDF 页面页面切换动画运行效果总结主

Qt QWidget实现图片旋转动画

《QtQWidget实现图片旋转动画》这篇文章主要为大家详细介绍了如何使用了Qt和QWidget实现图片旋转动画效果,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 一、效果展示二、源码分享本例程通过QGraphicsView实现svg格式图片旋转。.hpjavascript

【前端学习】AntV G6-08 深入图形与图形分组、自定义节点、节点动画(下)

【课程链接】 AntV G6:深入图形与图形分组、自定义节点、节点动画(下)_哔哩哔哩_bilibili 本章十吾老师讲解了一个复杂的自定义节点中,应该怎样去计算和绘制图形,如何给一个图形制作不间断的动画,以及在鼠标事件之后产生动画。(有点难,需要好好理解) <!DOCTYPE html><html><head><meta charset="UTF-8"><title>06

安卓链接正常显示,ios#符被转义%23导致链接访问404

原因分析: url中含有特殊字符 中文未编码 都有可能导致URL转换失败,所以需要对url编码处理  如下: guard let allowUrl = webUrl.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) else {return} 后面发现当url中有#号时,会被误伤转义为%23,导致链接无法访问

Flutter 进阶:绘制加载动画

绘制加载动画:由小圆组成的大圆 1. 定义 LoadingScreen 类2. 实现 _LoadingScreenState 类3. 定义 LoadingPainter 类4. 总结 实现加载动画 我们需要定义两个类:LoadingScreen 和 LoadingPainter。LoadingScreen 负责控制动画的状态,而 LoadingPainter 则负责绘制动画。

【iOS】MVC模式

MVC模式 MVC模式MVC模式demo MVC模式 MVC模式全称为model(模型)view(视图)controller(控制器),他分为三个不同的层分别负责不同的职责。 View:该层用于存放视图,该层中我们可以对页面及控件进行布局。Model:模型一般都拥有很好的可复用性,在该层中,我们可以统一管理一些数据。Controlller:该层充当一个CPU的功能,即该应用程序

用Unity2D制作一个人物,实现移动、跳起、人物静止和动起来时的动画:中(人物移动、跳起、静止动作)

上回我们学到创建一个地形和一个人物,今天我们实现一下人物实现移动和跳起,依次点击,我们准备创建一个C#文件 创建好我们点击进去,就会跳转到我们的Vision Studio,然后输入这些代码 using UnityEngine;public class Move : MonoBehaviour // 定义一个名为Move的类,继承自MonoBehaviour{private Rigidbo

动画AnimationDrawable、转动

现实开发中:很多地方都用到 点击动画的特效; 本案例本人做了三个关于“动” 画 的效果; 先上图: 总体图: A: B: 1:点击图片按钮,效果是:图片闪动; 通过在xml中定义:标签:animation-list来实现点击动画的效果;  是否循环标签:oneshot ;   时间间隔标签:duration ; 要显示的图片标签:drawable ;

13 transition数组的动画使用

划重点 动画:transitiontransition-group :数组动画数组的 添加 / 删除 豆腐粉丝汤 清淡又健康 <!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><me