60 lines
2.2 KiB
Swift
60 lines
2.2 KiB
Swift
import UIKit
|
|
|
|
/// 翻页控制器:管理 UIPageViewController 的创建、切换、故障修复和翻页请求队列。
|
|
///
|
|
/// RDReaderView 持有此控制器,将 pageCurl 模式的容器管理职责下沉。
|
|
struct RDReaderPagingController {
|
|
/// 当前 pageCurl 翻页请求模型
|
|
struct PageTransitionRequest: Equatable {
|
|
let pageNum: Int
|
|
let animated: Bool
|
|
}
|
|
|
|
/// 排队中的翻页请求(pageCurl 动画过程中收到新跳转时排队)
|
|
var pendingTransitionRequest: PageTransitionRequest?
|
|
|
|
/// 是否正在执行页面转场动画
|
|
var isTransitioning: Bool = false
|
|
|
|
/// UI 是否已经构建完成(避免重复构建)
|
|
var didBuildUI = false
|
|
|
|
// MARK: - PageViewController 工厂
|
|
|
|
/// 创建带指定 spine 位置的 UIPageViewController
|
|
static func createPageViewController(isDualPage: Bool) -> UIPageViewController {
|
|
let options: [UIPageViewController.OptionsKey: Any]?
|
|
if isDualPage {
|
|
options = [.spineLocation: NSNumber(value: UIPageViewController.SpineLocation.mid.rawValue)]
|
|
} else {
|
|
options = nil
|
|
}
|
|
let pageVC = UIPageViewController(transitionStyle: .pageCurl, navigationOrientation: .horizontal, options: options)
|
|
pageVC.isDoubleSided = isDualPage
|
|
return pageVC
|
|
}
|
|
|
|
// MARK: - 翻页请求队列管理
|
|
|
|
/// pageCurl 动画过程中如果收到新的跳转请求,则排队等待当前动画结束。
|
|
mutating func shouldQueuePageTransition(_ request: PageTransitionRequest, currentDisplayType: RDReaderView.DisplayType) -> Bool {
|
|
guard currentDisplayType == .pageCurl, isTransitioning else { return false }
|
|
pendingTransitionRequest = request
|
|
return true
|
|
}
|
|
|
|
/// 收尾 pageCurl 转场,返回排队中的后续请求(如果有的话)。
|
|
mutating func finishPageCurlTransition() -> PageTransitionRequest? {
|
|
isTransitioning = false
|
|
guard let pending = pendingTransitionRequest else { return nil }
|
|
pendingTransitionRequest = nil
|
|
return pending
|
|
}
|
|
|
|
/// 重置所有排队状态(用于故障修复)。
|
|
mutating func resetPendingState() {
|
|
isTransitioning = false
|
|
pendingTransitionRequest = nil
|
|
}
|
|
}
|