源码注释: - 为 ~60 个 Swift 文件补充缺失的 doc comment(file header、类型、属性、方法) - 修正 4 处错误注释:翻页模式数量、搜索行为描述、手势识别器描述、悬空文档块 文档维护: - 删除重复文档:WXRead/读书EPUB阅读器实现架构.md(与微信读书版完全一致) - 合并重叠文档:阅读器规划.md → 阅读器功能开发计划.md(单一真值) - 修正过时内容:所有文档中"四种翻页模式"→"三种",移除 horizontalCoverScroll - 更新架构图:补齐 EPUBUI/ReaderController、Paging/、Typesetter/ 等子目录 - 更新 index.md 索引:新增开发计划和架构对比文档引用
111 lines
4.8 KiB
Swift
111 lines
4.8 KiB
Swift
//
|
||
// RDReaderViewProtocols.swift
|
||
// ReadViewSDK
|
||
//
|
||
// 文件职责:阅读器核心协议定义,包括数据源、代理、页面提供者、页面导航等接口。
|
||
//
|
||
|
||
import UIKit
|
||
|
||
/// 阅读器数据源协议
|
||
/// 上层控制器通过实现此协议,向 RDReaderView 提供页面数量、内容视图和工具栏。
|
||
/// 所有方法由 RDReaderView 在需要渲染页面时回调。
|
||
@objc public protocol RDReaderDataSource: NSObjectProtocol {
|
||
/// 返回阅读器的总页数
|
||
func pageCountOfReaderView(readerView: RDReaderView) -> Int
|
||
/// 返回指定页码的内容视图
|
||
func pageContentView(readerView: RDReaderView, pageNum: Int, containerView: UIView?) -> UIView
|
||
/// 返回指定页码的唯一标识符,用于 UICollectionViewCell 复用
|
||
func pageIdentifier(readerView: RDReaderView, pageNum: Int) -> String?
|
||
/// 返回顶部工具栏视图(可选),点击屏幕中央时会显示/隐藏
|
||
@objc optional func topToolView(readerView: RDReaderView) -> UIView?
|
||
/// 返回底部工具栏视图(可选),点击屏幕中央时会显示/隐藏
|
||
@objc optional func bottomToolView(readerView: RDReaderView) -> UIView?
|
||
}
|
||
|
||
/// 与内容格式无关的统一分页提供者协议。
|
||
/// 逐步替代面向 EPUB 命名的 ``RDReaderDataSource``,方便后续复用到 PDF 等其他阅读场景。
|
||
@objc public protocol RDReaderPageProvider: NSObjectProtocol {
|
||
/// 返回阅读器的总页数
|
||
func numberOfPages(in readerView: RDReaderView) -> Int
|
||
/// 返回指定页码的内容视图,支持通过 reusableView 复用已有视图
|
||
func readerView(_ readerView: RDReaderView, viewForPageAt index: Int, reusableView: UIView?) -> UIView
|
||
/// 返回指定页码的唯一标识符,用于 UICollectionViewCell 复用
|
||
@objc optional func pageIdentifier(in readerView: RDReaderView, index: Int) -> String?
|
||
/// 返回顶部工具栏视图(可选)
|
||
@objc optional func readerViewTopChrome(_ readerView: RDReaderView) -> UIView?
|
||
/// 返回底部工具栏视图(可选)
|
||
@objc optional func readerViewBottomChrome(_ readerView: RDReaderView) -> UIView?
|
||
}
|
||
|
||
/// 阅读器代理协议
|
||
/// 上层控制器通过实现此协议,接收翻页和横竖屏切换事件
|
||
@objc public protocol RDReaderDelegate: NSObjectProtocol {
|
||
/// 翻页回调,当当前显示页码变化时触发
|
||
func pageNum(readerView: RDReaderView, pageNum: Int)
|
||
/// 横竖屏切换时回调,可在此重新分页
|
||
@objc optional func readerViewOrientationWillChange(readerView: RDReaderView, isLandscape: Bool)
|
||
}
|
||
|
||
/// 阅读器页面导航协议
|
||
/// 提供与具体实现无关的页面导航接口,外部可通过此协议控制翻页和刷新。
|
||
public protocol RDReaderPageNavigating: AnyObject {
|
||
/// 当前显示的页码
|
||
var currentPage: Int { get }
|
||
/// 重新加载所有页面数据
|
||
func reloadPages()
|
||
/// 跳转到指定页码,可选是否带动画
|
||
func transition(to page: Int, animated: Bool)
|
||
}
|
||
|
||
// MARK: - 枚举
|
||
|
||
extension RDReaderView {
|
||
/// 翻页模式枚举,决定 RDReaderView 使用哪种底层视图来展示内容
|
||
public enum DisplayType {
|
||
/// 仿真翻页:使用 UIPageViewController,模拟真实翻书效果
|
||
case pageCurl
|
||
/// 水平滚动:使用 UICollectionView + 自定义布局,每屏一项,水平分页
|
||
case horizontalScroll
|
||
/// 垂直滚动:使用 UICollectionView,全宽项目,垂直连续滚动
|
||
case verticalScroll
|
||
}
|
||
|
||
/// 翻页方向枚举
|
||
public enum PageDirection {
|
||
/// 从左往右翻页(默认,适用于中文/英文书籍)
|
||
case leftToRight
|
||
/// 从右往左翻页(适用于日文漫画等)
|
||
case rightToLeft
|
||
}
|
||
}
|
||
|
||
// MARK: - Legacy 适配器
|
||
|
||
/// 旧版数据源适配器
|
||
/// 将 ``RDReaderDataSource`` 协议适配为 ``RDReaderPageProvider``,实现渐进式迁移。
|
||
final class RDReaderLegacyDataSourceAdapter: NSObject, RDReaderPageProvider {
|
||
/// 被适配的旧版数据源
|
||
weak var dataSource: RDReaderDataSource?
|
||
|
||
func numberOfPages(in readerView: RDReaderView) -> Int {
|
||
dataSource?.pageCountOfReaderView(readerView: readerView) ?? 0
|
||
}
|
||
|
||
func readerView(_ readerView: RDReaderView, viewForPageAt index: Int, reusableView: UIView?) -> UIView {
|
||
dataSource?.pageContentView(readerView: readerView, pageNum: index, containerView: reusableView) ?? UIView()
|
||
}
|
||
|
||
func pageIdentifier(in readerView: RDReaderView, index: Int) -> String? {
|
||
dataSource?.pageIdentifier(readerView: readerView, pageNum: index)
|
||
}
|
||
|
||
func readerViewTopChrome(_ readerView: RDReaderView) -> UIView? {
|
||
dataSource?.topToolView?(readerView: readerView)
|
||
}
|
||
|
||
func readerViewBottomChrome(_ readerView: RDReaderView) -> UIView? {
|
||
dataSource?.bottomToolView?(readerView: readerView)
|
||
}
|
||
}
|