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
|
||
}
|
||
}
|