FSCalendar 源码解析(一):整体架构与核心组件深度剖析

📅 发布时间:2026/9/19 13:17:35
FSCalendar 源码解析(一):整体架构与核心组件深度剖析
FSCalendar 源码解析一整体架构与核心组件深度剖析【免费下载链接】FSCalendarA fully customizable iOS calendar library, compatible with Objective-C and Swift项目地址: https://gitcode.com/gh_mirrors/fs/FSCalendarFSCalendar 是一款高度可定制的 iOS 日历控件库同时支持 Objective-C 与 Swift被超过 10,000 个 App 采用。本文带你深入 FSCalendar 源码剖析它的整体架构、核心组件职责与经典设计模式帮助你在 10 分钟内看懂这个日历库怎么搭起来的。核心关键词FSCalendar 源码解析、iOS 日历控件架构、CalendarView 核心组件 一分钟了解 FSCalendarFSCalendar 本质上是一个伪装成 UIView 的日历容器它内部组合了以下5 类核心组件组件文件一句话职责主控制器FSCalendar.m组装视图树、处理选择/滚动/翻页逻辑渲染引擎FSCalendarCollectionViewLayout.m自定义 UICollectionView 布局计算每个日期的格子位置日期计算器FSCalendarCalculator.mNSDate与IndexPath互译的翻译官外观中枢FSCalendarAppearance.m统一管理所有颜色、字体、偏移量委托代理FSCalendarDelegationProxy.m让日历支持多委托共存 记住这张表后面每个组件都会展开讲。 目录结构导览整个仓库非常精简核心源码全部集中在 FSCalendar/ 目录下FSCalendar/FSCalendar.h —— 对外主接口定义了FSCalendarDataSource、FSCalendarDelegate、FSCalendarDelegateAppearance三大协议FSCalendar/include/ —— 打包成 Framework 时暴露的头文件清单Example-Objc/ —— Objective-C 完整示例工程DIY 日历、区间选择、范围切换等 DemoExample-Swift/ —— Swift 示例工程Example-TodayExtension/ —— Today 小组件集成示例FSCalendar.podspec、Package.swift —— CocoaPods 与 SPM 两种集成方式的描述文件核心源码只有16 对 .h/.m 文件全部围绕主控件 渲染 计算 外观 委托五大职责展开规模小但分工极清晰非常适合做源码学习。️ 核心组件一FSCalendar 主控制器FSCalendar.h 中声明的FSCalendar继承自UIView并标记了IB_DESIGNABLE因此可以直接拖进 Interface Builder 可视化调参见 FSCalendar (IBExtension) 中的IBInspectable属性。打开 FSCalendar.m 的initialize方法约 146 行起能看到整个日历的装配流水线创建外观对象_appearance [[FSCalendarAppearance alloc] init]并让它反向持有日历创建日期工具NSCalendargregorianNSDateFormatter负责所有日期运算搭建视图层级contentView → daysContainer → collectionView日历的月视图本质是嵌在容器里的一个 CollectionView注册三种可复用视图日期格子FSCalendarCell、空白占位格FSCalendarBlankCell、吸顶头FSCalendarStickyHeader挂载两个助手transitionCoordinator过渡动画协调器和calculator日期计算器初始化两个委托代理dataSourceProxy与delegateProxy由 FSCalendarDelegationFactory 生产。关键发现主控件还重写了setValue:forUndefinedKey:FSCalendar.m#L261-L280把 XIB 中无法识别的属性动态转发给 appearance 或 layout——这就是为什么在 Storyboard 里能直接配置titleDefaultColor这类日历本体并不存在的属性非常巧妙。⚙️ 核心组件二CollectionView 与自定义 Layout日历的翻页并不是真的在滚日历而是每个 Section 代表一个月/一周横滑切换 Section。这由两个类实现FSCalendarCollectionView —— 对UICollectionView的轻量封装增加了一个internalDelegate内部回调通道FSCalendarCollectionViewLayout —— 继承UICollectionViewLayout是整个日历渲染的心脏它决定日期格子如何按 7 列排布月份头部Section Header如何溶解滚动时淡出/淡入占位日期上月/下月补位格如何定位。这种UICollectionView 自定义 Layout的组合是 FSCalendar 高性能的关键格子复用、按需绘制、滚动流畅全部交给系统成熟机制。 核心组件三FSCalendarCalculator 日期计算器日历控件最棘手的问题是2026 年 9 月 18 日和第 3 页第 5 格是两套坐标系必须在它们之间反复换算。FSCalendar 把这件事全部封装进了 FSCalendarCalculator它提供三组互译接口日期 ↔ IndexPathdateForIndexPath:与indexPathForDate:atMonthPosition:scope:同一个日期在不同月份位置上/本/下月和不同视图范围月/周下会算出不同的格子Section ↔ 页面monthForSection:、weekForSection:、pageForSection:把 Section 号还原成具体月份/周占位与行数numberOfHeadPlaceholdersForMonth:月初需要补几个灰格子、numberOfRowsInMonth:这个月要占 5 行还是 6 行。 这就是典型的Calculator 模式把纯计算逻辑从 UI 代码中剥离FSCalendar.m中所有日期换算都委托给它主控制器因此保持干净。 核心组件四FSCalendarAppearance 外观中枢想改日历的某个颜色去 FSCalendarAppearance.h 就能找到对应属性titleDefaultColor未选中日字色、fillSelectionColor选中填充色、borderRadius、weekdayFont……几乎所有视觉参数都收敛在这一个对象里。它还定义了格子状态枚举FSCalendarCellStateFSCalendarCellStateNormal / Selected / Placeholder / Disabled / Today / Weekend配合FSCalendarDelegateAppearance协议定义在 FSCalendar.h#L158 起FSCalendar 实现了全局外观 按日期精细覆盖的双层定制体系全局直接改calendar.appearance的属性按天在代理方法中针对特定日期返回不同颜色/圆角/偏移例如把工作日和周末画成两种风格。 核心组件五Delegation Proxy 多委托机制UIView原生只允许一个 delegate但实际开发中父页面、弹窗管理器、数据层往往都想监听日期选中事件。FSCalendar 的解法是Proxy 模式FSCalendarDelegationProxy 维护一个委托队列FSCalendar内部只和 Proxy 打交道Proxy 再把调用按优先级分发给所有注册的委托对象FSCalendarDelegationFactory 用工厂方法分别产出 dataSource 版和 delegate 版代理。结果你随时可以追加一个 delegate比如埋点组件无需覆盖已有委托——这在开源日历库里是相当少见的友好设计。 辅助组件速览组件文件作用过渡协调器FSCalendarTransitionCoordinator.m月/周模式切换scope 手势时的缩放动画与布局过渡月份标题头FSCalendarHeaderView.m显示9月等标题滚动时做溶解效果吸顶头FSCalendarStickyHeader.m非分页模式下滚动到月份边界时吸附显示月份标题星期头FSCalendarWeekdayView.m渲染日一二三四五六支持zh-CN等多语言 locale日期格子FSCalendarCell.m单个日期格子视图数字、副标题、事件圆点、圆角边框点击分发器FSCalendarDynamicHeader.h点击月份标题直接跳转该月HeaderTouchDeliver工具扩展FSCalendarExtensions.mNSDate/NSCalendar 的便捷分类方法 设计模式总结FSCalendar 的代码量不大但模式运用得相当完整值得逐个对照源码学习组合优于继承FSCalendar 不继承 UIScrollView而是组合 CollectionView行为更可控DataSource / Delegate数据事件数、副标题与行为选中回调分离与 UICollectionView 一脉相承降低学习成本Calculator 模式日期与坐标系的换算独立成类Proxy 模式多委托共存Coordinator 模式FSCalendarTransitionCoordinator把月↔周切换动画从主流程中剥离单元格复用基于 UICollectionView 的 Cell 复用机制保证流畅滚动。源码阅读路线建议先读 FSCalendar.m 的initialize与layoutSubviews→ 再看 FSCalendarCalculator.h 的接口设计 → 最后对照 Example-Objc/DIYExampleViewController.m 等示例验证理解。 小结与下篇预告FSCalendar 的架构可以浓缩为一句话主控制器负责编排Layout 负责渲染Calculator 负责换算Appearance 负责颜值Proxy 负责协作。五个组件各司其职才让一个日期格子网格变得既可定制又高效。⏭️下篇预告源码解析二我们将深入日期选中与范围选择的状态流转、月/周 scope 切换动画的完整实现以及 Today Extension 小组件的集成细节。更多使用技巧可参考 MOREUSAGE.md 与 README.md。【免费下载链接】FSCalendarA fully customizable iOS calendar library, compatible with Objective-C and Swift项目地址: https://gitcode.com/gh_mirrors/fs/FSCalendar创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考