news 2026/8/22 15:01:04

深度剖析Cheetah核心架构:Cheetah、CheetahGroup与CheetahProperty三层设计揭秘

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
深度剖析Cheetah核心架构:Cheetah、CheetahGroup与CheetahProperty三层设计揭秘

深度剖析Cheetah核心架构:Cheetah、CheetahGroup与CheetahProperty三层设计揭秘

【免费下载链接】CheetahEasy animation library on iOS with Swift2项目地址: https://gitcode.com/gh_mirrors/chee/Cheetah

Cheetah 是一款用 Swift 编写的轻量级 iOS 动画库,它不依赖系统的动画 API,而是通过一个简单的 CADisplayLink 运行循环逐帧修改视图属性,从而实现移动、旋转、缩放、颜色渐变等丰富动画效果。本文将带你用通俗的方式看懂它的三层核心架构:Cheetah(动画导演)、CheetahGroup(并行动画组)、CheetahProperty(动画最小单元),帮你在阅读源码时迅速建立心智模型。

为什么一个小型动画库需要"三层"结构?

很多新手写动画时会把所有逻辑塞进一个类里,结果代码越写越乱。Cheetah 只用不到 2000 行代码就把"动画怎么编排、怎么并行、怎么逐帧计算"三件事拆得清清楚楚:

层级类名职责所在文件
导演层Cheetah接收链式调用、编排顺序、控制播放Cheetah/Cheetah.swift
分组层CheetahGroup管理同一批并行动画、统一时长与锚点Cheetah/CheetahGroup.swift
单元层CheetahProperty单个属性的插值计算与视图更新Cheetah/CheetahProperties.swift

这种分层就像拍电影:导演决定拍什么顺序,场组负责同一场的几个镜头同时拍摄,演员(属性)各自完成自己的表演。

第一层:Cheetah —— 你的动画"总导演"

一切从UIView.cheetah这个属性开始。它是一个通过关联对象(Associated Object)挂载到每个视图上的 Cheetah 实例,每个视图都能独立持有自己的动画序列,源码见 Cheetah/UIView+CheetahAnimation.swift。

Cheetah 类的设计精髓在于流式 API(Fluent API)。你调用它的任何一个方法——movescalerotatealphaduration……最后都会返回self,从而可以自由地链式书写:

box.cheetah.move(100, 0).duration(0.5).run()

链式调用背后其实只有两条主线:

  • 加属性:每个动画方法(如move)会创建一个具体的 Property 对象,并通过addProperty塞入"当前组";
  • 加分组:调用wait()时会addGroup()开一个新组,之前的属性就归到上一组执行——这正是"串行/并行"编排的秘密。

此外,Cheetah 还管理着播放状态(runningpausedgroupIndexrepeatCount),并支持anchorTopanchorCenter等锚点快捷属性,让你在旋转、缩放时自由指定中心点。真正开始播放时,run()只做一件事:把自身注册进全局的 CheetahManager,然后坐等每一帧的"催促"。

第二层:CheetahGroup —— 让动画"同时发生"的容器

CheetahGroup 非常"薄",它自己不做任何计算,只负责聚合与调度

  • 持有本组的properties数组、统一的durationdelayanchorPoint
  • 每帧被proceed(dt)驱动时,先累加已用时间,未到delay就直接返回,等待下一帧;
  • 到达时间后,遍历组内所有属性:每个属性各自推进并返回一个CATransform3D变换矩阵,Group 把它们依次拼接后一次性赋给view.layer.transform

这就是为什么以下三个动作会"同时"发生——它们属于同一个 Group:

view.cheetah .move(100, 0) .rotate(M_PI * 2) .scale(1.5) .run()

而位置、大小这类不走变换矩阵的属性,则由各自的 Property 直接写入视图。Group 全部属性完成后返回true,Cheetah 就会把groupIndex前进一格,推进到下一组——串行动画就此实现。

第三层:CheetahProperty —— 动画的最小计算单元

CheetahProperty 是整个架构里"干活最多"的一层,但它的基类(Cheetah/CheetahProperties.swift)设计得极其克制,只定义了一个清晰的三阶段生命周期

  1. prepare():动画开始(或循环回来)时,记录当前值from并清零计时;
  2. calc():结合"绝对/相对"标志算出目标值toCalc(比如move(100, 0)的终点就是当前位置加 100);
  3. update():每帧根据进度current插值,把结果写回视图。

进度推进的核心是proceed(dt):把elapsed累加到delay + duration为止,并支持两种节奏——

  • 缓动(Easing):通过Easings提供的 30+ 种缓动函数(正弦、弹性、回弹、贝塞尔曲线等,源码见 Cheetah/Easings.swift)做非线性插值;
  • 弹簧(Spring):基于张力与摩擦的半隐式欧拉积分,模拟真实物理回弹,源码见 Cheetah/Spring.swift。

在这套通用骨架之下,具体属性被按动画对象分成了四个文件,各管一摊:

  • Cheetah/CheetahViewProperties.swift:framesizealphabackgroundColor等视图级属性;
  • Cheetah/CheetahLayerProperties.swift:positionrotationscale、圆角、边框等图层属性;
  • Cheetah/CheetahLabelProperties.swift:textColor等文本属性;
  • Cheetah/CheetahConstraintProperties.swift:Auto Layout 约束的constant动画。

由于基类是open的,你还可以继承 CheetahProperty 自定义任意属性的动画——这是该库"想动什么就能动什么"的底气所在。

幕后推手:CheetahManager 的显示循环

三层结构要跑起来,还需要一个"心跳"。Cheetah/CheetahManager.swift 中的 CheetahManager 是全局单例,它用CADisplayLink与屏幕刷新同步:

  • 第一个 Cheetah 调用run()时,管理器启动 DisplayLink;
  • 每帧计算与上一帧的时间差dt,依次驱动所有在跑的动画,动画结束后自动清理、解除视图上的关联对象;
  • 当所有动画都完成后,DisplayLink 自动销毁——零动画时零开销,这对性能敏感的应用非常友好。

同时它提供了全局的pause()/resume()/stop(),方便在页面切换等场景整体暂停动画。

小结:这套三层设计教给我们什么?

🎯职责单一:导演编排、分组调度、单元计算,各自独立,互不越界; 🎯数据驱动:动画不是一步到位的"起点到终点",而是每帧根据dt增量推进,因此天然支持暂停、循环、相对偏移; 🎯可扩展性:新增一种属性只需继承 CheetahProperty 实现三个小方法,主架构一行不用改; 🎯性能自觉:单例管理器 + 按需启停的 CADisplayLink,让小库也有大库级的资源意识。

当你下次想动手写一个 iOS 动画库,或者阅读其他动画框架源码时,不妨对照这三层去拆解:先问"谁在编排顺序",再问"谁负责并行",最后问"谁在算每一帧的数值"——答案往往就浮出水面了。

【免费下载链接】CheetahEasy animation library on iOS with Swift2项目地址: https://gitcode.com/gh_mirrors/chee/Cheetah

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/22 14:54:32

MobilityDB上云部署指南:AWS、Azure、GCP三大云平台迁移全解析

MobilityDB上云部署指南:AWS、Azure、GCP三大云平台迁移全解析 【免费下载链接】MobilityDB MobilityDB is a geospatial trajectory data management & analysis platform, built on PostgreSQL and PostGIS. 项目地址: https://gitcode.com/gh_mirrors/mo/M…

作者头像 李华
网站建设 2026/8/22 14:53:21

CityPicker城市选择器:快速搭建Android省市区地址选择组件

CityPicker城市选择器:快速搭建Android省市区地址选择组件 【免费下载链接】citypicker citypicker城市选择器,详细的省市区地址信息,支持仿iOS滚轮实现,仿京东样式,一级或者三级列表展示方式。 项目地址: https://g…

作者头像 李华