refactor: split reader architecture and chrome handling
This commit is contained in:
@@ -0,0 +1,90 @@
|
||||
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
|
||||
func readerView(_ readerView: RDReaderView, viewForPageAt index: Int, reusableView: UIView?) -> UIView
|
||||
@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 适配器
|
||||
|
||||
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)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user