PaperFold-for-iOS架构深度剖析:PaperFoldView、FoldView、MultiFoldView五大核心类如何协作
【免费下载链接】PaperFold-for-iOSPaper folding animation for iOS项目地址: https://gitcode.com/gh_mirrors/pa/PaperFold-for-iOS
PaperFold-for-iOS是一个经典的 iOS 纸折叠动画控件(Paper folding animation for iOS):拖拽中间的"纸张",左右或上下的视图会像折纸一样层层展开,阴影和截图拼接营造出逼真的立体折叠效果。本文将带你从零看懂它由 PaperFoldView、FoldView、MultiFoldView、FacingView、ShadowView 五大核心类构成的协作架构,适合想学习 UIKit 动画机制的开发者。
🗂️ 先建立全局:四层架构一览
整个项目源码集中在 PaperFold/PaperFold/PaperFold/ 目录下,类之间的关系可以概括为一条清晰的调用链:
| 层级 | 类 | 职责 |
|---|---|---|
| 总控层 | PaperFoldView | 手势识别、状态机、定时器驱动动画 |
| 组合层 | MultiFoldView/FoldView | 多折扇形展开 / 单折(一对折面) |
| 渲染层 | FacingView+ShadowView | 单张折面 + 渐变阴影 |
| 工具层 | UIView+Screenshot等 | 视图截图、阴影绘制 |
全局常量(折叠方向、状态枚举、阈值)统一定义在 PaperFoldConstants.h 中,例如PaperFoldState枚举描述了默认、左/右/上/下展开、过渡六种状态,是贯穿所有类的"状态语言"。
🧩 五大核心类逐一拆解
1. PaperFoldView:动画的总指挥
PaperFoldView.h 是唯一需要业务代码直接接触的类。它内部持有四个方向的折叠容器:
bottomFoldView(单个FoldView,左/下侧只支持一层折叠)leftFoldView、rightFoldView、topFoldView(均为MultiFoldView,支持多层折叠)
它做了三件关键事:
- 手势驱动:给中间内容视图挂上
UIPanGestureRecognizer,手指滑动时调用animateWithContentOffset:panned:把偏移量实时分发给各折叠视图(见 PaperFoldView.m)。 - 定时器补帧:手指松手后,用一个每 0.01 秒触发一次的
NSTimer(animationTimer)持续推进一步偏移量,让折叠动画"惯性"走完——这是它能做到拖拽与惯性无缝衔接的核心技巧。 - 状态回调:通过
PaperFoldViewDelegate协议通知外部折叠状态变化,且能区分是手势触发还是代码自动触发。
2. MultiFoldView:多层"手风琴"效应
MultiFoldView.h 负责右侧(及上侧)的多层折叠。两个关键参数决定了它的"手感":
numberOfFolds:折叠层数,内部按层数创建多个FoldView;pullFactor(拉力系数):控制各层展开的先后节奏——离中心近的折先张开,远处的折按比例延迟跟随,形成逼真的手风琴波浪感。
每次状态变化时,它调用unfoldViewToFraction:把 0~1 的展开比例逐级分配给内部各FoldView。
3. FoldView:最小的"一张纸"
FoldView.h 是单折的基本单元,内部恰好由两个背靠背的FacingView(left/right 或 top/bottom)组成,模拟一张纸正反两个面。它的关键方法drawScreenshotOnFolds会把内容视图的截图裁剪拼接到两个折面上——这就是折叠时"纸面"上内容看似连续不撕裂的秘诀。
4. FacingView + ShadowView:折面与光影
FacingView.h 很薄,它只是折面容器;真正的立体感来自 ShadowView.h——它用CAGradientLayer绘制一条渐变阴影。作者设定虚拟光源在屏幕右侧,因此朝向左的折面更暗、朝向右的更亮,折叠角度变化时阴影深浅随之更新,二维视图就有了三维质感。
5. 辅助类:让体验完整
- TouchThroughUIView.h:可穿透点击的内容视图容器,让折叠视图不影响下层交互;
- UIView+Screenshot.h:把任意 UIView 渲染成
UIImage的类别扩展,useOptimizedScreenshot属性可控制是否按屏幕 Retina 比例截图以优化性能; - PaperFoldNavigationController.m:把折叠封装成导航控制器,实现"折叠式"页面转场;
- PaperFoldSwipeHintView.m:首次使用时展示的左右滑动引导提示。
⚙️ 一次折叠动画的完整流程
把上面这些串起来,拖拽展开右侧视图时的执行链是:
- 手指滑动 →
UIPanGestureRecognizer产生偏移量; PaperFoldView.animateWithContentOffset:panned:把偏移量传给rightFoldView;MultiFoldView.unfoldWithParentOffset:按pullFactor把偏移量拆分给每层FoldView;- 每个
FoldView更新两个FacingView的 frame,并刷新ShadowView的渐变阴影; - 手势结束 →
NSTimer每 0.01s 继续推进偏移量,直至越过 0.3 的展开阈值(kRightViewUnfoldThreshold,定义于 PaperFoldConstants.h)触发foldDidOpened,动画收尾。
整个过程中,偏移量(offset)是唯一的"动画源",所有视图只负责把自己的几何状态映射到偏移量上——这种"单一数据源驱动多视图"的设计,是本项目最值得借鉴的架构思想。
🚀 快速上手:三步集成
- 引入源码文件,添加
PaperFoldView到视图控制器; - 设置四个方向的内容(任意
UIView均可,示例见 DemoRootViewController.m):[_paperFoldView setRightFoldContentView:mapView foldCount:3 pullFactor:0.9]; [_paperFoldView setCenterContentView:centerTableView]; - 需要代码控制展开/收起时,直接调用状态接口:
[self.paperFoldView setPaperFoldState:PaperFoldStateRightUnfolded animated:YES];项目要求使用 ARC,支持 CocoaPods 集成(见 PaperFold.podspec),完整演示工程在 PaperFold-NavDemo/ 目录。
📌 总结
PaperFold-for-iOS 用不到十个类,就实现了一个教科书级的 2D 模拟 3D 折叠动画:PaperFoldView 负责"指挥",MultiFoldView 负责"节奏",FoldView 负责"结构",FacingView + ShadowView 负责"观感"。如果你想给 iOS 应用加上类似 Google Now 的侧边栏折叠效果,或想深入理解手势驱动的帧同步动画,这个项目的 PaperFold/PaperFold/PaperFold/ 源码非常值得一读。
【免费下载链接】PaperFold-for-iOSPaper folding animation for iOS项目地址: https://gitcode.com/gh_mirrors/pa/PaperFold-for-iOS
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考