拓冰建站拓冰建站
首页 / 资讯中心 / 正文

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

深度剖析Cheetah核心架构Cheetah、CheetahGroup与CheetahProperty三层设计揭秘【免费下载链接】CheetahEasy animation library on iOS with Swift2项目地址: https://gitcode.com/gh_mirrors/chee/CheetahCheetah 是一款用 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/UIViewCheetahAnimation.swift。Cheetah 类的设计精髓在于流式 APIFluent API。你调用它的任何一个方法——move、scale、rotate、alpha、duration……最后都会返回self从而可以自由地链式书写box.cheetah.move(100, 0).duration(0.5).run()链式调用背后其实只有两条主线加属性每个动画方法如move会创建一个具体的 Property 对象并通过addProperty塞入当前组加分组调用wait()时会addGroup()开一个新组之前的属性就归到上一组执行——这正是串行/并行编排的秘密。此外Cheetah 还管理着播放状态running、paused、groupIndex、repeatCount并支持anchorTop、anchorCenter等锚点快捷属性让你在旋转、缩放时自由指定中心点。真正开始播放时run()只做一件事把自身注册进全局的 CheetahManager然后坐等每一帧的催促。第二层CheetahGroup —— 让动画同时发生的容器CheetahGroup 非常薄它自己不做任何计算只负责聚合与调度持有本组的properties数组、统一的duration、delay和anchorPoint每帧被proceed(dt)驱动时先累加已用时间未到delay就直接返回等待下一帧到达时间后遍历组内所有属性每个属性各自推进并返回一个CATransform3D变换矩阵Group 把它们依次拼接后一次性赋给view.layer.transform。这就是为什么以下三个动作会同时发生——它们属于同一个 Groupview.cheetah .move(100, 0) .rotate(M_PI * 2) .scale(1.5) .run()而位置、大小这类不走变换矩阵的属性则由各自的 Property 直接写入视图。Group 全部属性完成后返回trueCheetah 就会把groupIndex前进一格推进到下一组——串行动画就此实现。第三层CheetahProperty —— 动画的最小计算单元CheetahProperty 是整个架构里干活最多的一层但它的基类Cheetah/CheetahProperties.swift设计得极其克制只定义了一个清晰的三阶段生命周期prepare()动画开始或循环回来时记录当前值from并清零计时calc()结合绝对/相对标志算出目标值toCalc比如move(100, 0)的终点就是当前位置加 100update()每帧根据进度current插值把结果写回视图。进度推进的核心是proceed(dt)把elapsed累加到delay duration为止并支持两种节奏——缓动Easing通过Easings提供的 30 种缓动函数正弦、弹性、回弹、贝塞尔曲线等源码见 Cheetah/Easings.swift做非线性插值弹簧Spring基于张力与摩擦的半隐式欧拉积分模拟真实物理回弹源码见 Cheetah/Spring.swift。在这套通用骨架之下具体属性被按动画对象分成了四个文件各管一摊Cheetah/CheetahViewProperties.swiftframe、size、alpha、backgroundColor等视图级属性Cheetah/CheetahLayerProperties.swiftposition、rotation、scale、圆角、边框等图层属性Cheetah/CheetahLabelProperties.swifttextColor等文本属性Cheetah/CheetahConstraintProperties.swiftAuto 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),仅供参考
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门