【免费下载链接】DGActivityIndicatorView
DGActivityIndicatorView is a great way to make loading spinners in your application look nicer. It contains 32 different indicator view styles.
DGActivityIndicatorView 是一个经典的 iOS 加载动画开源库,内置 32 种开箱即用的 loading spinner 样式。它不仅是加载动画组件,更是学习 Objective-C 设计模式的优秀样板——工厂方法、策略模式与模板方法在这里各司其职,完成了从"固定 32 种"到"无限扩展"的架构演进。本文带你读懂它的设计骨架。📖
一分钟认识 DGActivityIndicatorView 加载动画库
这个库解决的问题很简单:App 里的系统默认菊花不好看。它用一个UIView子类 DGActivityIndicatorView 封装了全部能力,对外只暴露 4 个属性/方法:
| 成员 | 作用 |
|---|---|
type | 选择 32 种动画样式之一 |
tintColor | 动画颜色 |
size | 动画尺寸 |
startAnimating/stopAnimating | 启停控制 |
样式由一个枚举统一定义,共 32 个 case,从 NineDots 到 BallSpinFadeLoader。想快速上手,只需一行pod 'DGActivityIndicatorView',官方 demo 在 DGActivityIndicatorExample/ViewController.m 里把 32 种动画铺成了 5×7 的网格,一目了然。
架构速览:三核心文件撑起整个库
整个库的代码组织极其克制,核心就三层:
- 视图层—— DGActivityIndicatorView.m:负责布局、启停、参数变化时重建动画
- 契约层—— DGActivityIndicatorAnimationProtocol.h:一条协议定义所有动画的唯一职责
- 实现层—— DGActivityIndicatorView/Animations/:32 个动画类,每类一个文件,互不依赖
下面逐个拆解背后隐藏的设计模式。🧩
模式一 | 工厂方法:32 种加载动画的"调度台"
视图从不alloc具体的动画类,而是调用工厂方法 activityIndicatorAnimationForAnimationType::一个switch语句,枚举值进,动画实例出。
这种"枚举 → 实例"的映射结构带来了两个好处:
- 调用方零心智负担:业务代码只写
DGActivityIndicatorAnimationTypeBallPulse,不用关心类名和构造细节 - 扩展点收敛:新增样式时,注册只发生在一个地方,不会散落各处
这是最朴素的工厂方法用法——没有复杂的重构痕迹,却精准划定了"谁来创建动画"的职责边界。
模式二 | 策略模式:协议里只写一行契约
真正让架构可扩展的,是这个只有一条方法的协议:
setupAnimationInLayer:withSize:tintColor:—— 把动画装进给定的 Layer。
视图持有的是id<DGActivityIndicatorAnimationProtocol>而非任何具体类,见 setupAnimation。这正是策略模式的精髓:
- 策略可互换:32 种动画对视图而言完全等价,随时替换
- 开闭原则:视图代码对扩展开放(新动画随时加入)、对修改关闭(视图层一行不用改)
协议刻意不规定"用什么动画对象、怎么排版",把实现自由度完整让给每个策略,这是它保持轻量(每个动画类平均不到 50 行)的关键。
模式三 | 模板方法:基类提供公共工具
32 个动画类都不是从零实现协议的,而是继承基类 DGActivityIndicatorAnimation。基类在 实现文件 里准备好了三个"半成品":
createBasicAnimationWithKeyPath:—— 创建不会在完成时移除的基础动画createKeyframeAnimationWithKeyPath:—— 创建关键帧动画createAnimationGroup—— 创建动画组
子类只需重写setupAnimationInLayer:withSize:tintColor:,调用这些工具即可组装出成品。以 BallPulse 动画 为例:3 个圆、1 个关键帧动画、错峰延迟——全部是基类工具的组合拳。这就是模板方法模式的变体:把"流程骨架"留在基类,把"具体画法"下放到子类,重复代码被压到最低。
自定义加载动画扩展指南:3 步从 32 变 33
理解了三大模式,扩展路径自然清晰。给 DGActivityIndicatorView 加一个自己的 loading 动画,只需三步:
- 加枚举值:在 DGActivityIndicatorAnimationType 中新增一个 case
- 写策略类:在 Animations 目录 新建一个继承自
DGActivityIndicatorAnimation的类,实现唯一的setupAnimationInLayer:...方法 - 注册进工厂:在 工厂 switch 里加一个 case,并在文件头部 import 新类
三步之后,demo 工程里加一行枚举引用即可预览效果。整个过程不触碰视图层的任何逻辑——这就是"无限扩展"的真正含义:扩展成本是常数级的,而不是随样式数量增长的。
💡 提示:本地体验可先克隆仓库:
git clone https://gitcode.com/gh_mirrors/dg/DGActivityIndicatorView,用 Xcode 打开示例工程即可运行。
生命周期细节:参数变化时动画如何重建
架构的最后一块拼图在 setter 与布局回调 里:
- 改
type、tintColor或size,都会触发setupAnimation重建动画 layoutSubviews中会先停 → 重建 → 再启,保证尺寸变化后动画精准铺满新区域- 启动/停止动画仅靠
speed = 1.0 / 0.0实现,开销极小,且支持随时无缝恢复
这套"声明式参数 + 响应式重建"的写法,让调用方无论何时改参数,界面都始终一致,无需手动清理旧动画。⚙️
总结:三种设计模式,一条核心契约
| 设计模式 | 在库中的位置 | 解决的问题 |
|---|---|---|
| 工厂方法 | 枚举→实例的 switch | 创建逻辑收敛,调用方无需知道类名 |
| 策略模式 | 一行方法协议 | 32 种动画可互换,视图层零修改扩展 |
| 模板方法 | 基类动画工具 | 消除子类间重复的动画搭建代码 |
DGActivityIndicatorView 的代码量极小,却把"如何设计一个可无限扩展的组件族"讲得明明白白:用协议划定边界,用工厂管理创建,用基类沉淀公共流程。如果你正在寻找学习 iOS 加载动画设计模式的样本,这个库值得逐行精读。✨
【免费下载链接】DGActivityIndicatorView
DGActivityIndicatorView is a great way to make loading spinners in your application look nicer. It contains 32 different indicator view styles.
相关推荐
Qwen3-32B模型可扩展性设计:从32B到更大规模模型的架构演进
Qwen3 32B模型可扩展性设计:从32B到更大规模模型的架构演进 引言:大语言模型的可扩展性挑战 你是否在训练大型语言模型时遇到过这些问题?随着模型参数规模
基础模型大模型人工智能NLPvscode-debug-visualizer扩展架构演进:从1.0到最新版的设计变化
vscode debug visualizer扩展架构演进:从1.0到最新版的设计变化 引言:调试可视化的架构挑战 你是否曾在调试复杂数据结构时,因无法直观感知
开发工具数据可视化终极指南:如何在Android手机上实现C++原生开发?Termux-NDK完整解决方案
终极指南:如何在Android手机上实现C++原生开发?Termux NDK完整解决方案 你是否曾想过,能否在Android手机上直接进行C/C++原生开发,摆
开发工具构建工具编译器
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考