feat: EPUB阅读器搜索、注释、CFI模块及大书远距跳转优化
- 实现EPUB阅读器搜索功能及选中注释功能 - 优化CFI模块,修复代码审查发现的11个问题 - 实现大书远距目录跳转与后台补全优化方案 - 优化设置面板与章节运行时联动 - 重构及大量改进优化
This commit is contained in:
@@ -1,17 +1,8 @@
|
||||
// RDEPUBReaderController+RuntimeBridge.swift
|
||||
// EPUB 阅读器运行时桥接层
|
||||
// 将阅读器控制器的公开行为委托给 runtime 对象执行,涵盖配置应用、
|
||||
// 出版物加载与分页、阅读位置恢复、加载状态管理、错误处理等生命周期操作。
|
||||
|
||||
import UIKit
|
||||
|
||||
/// RDEPUBReaderController 运行时桥接扩展
|
||||
///
|
||||
/// 本文件将阅读器控制器的公开行为委托给 runtime 对象执行,涵盖配置应用、
|
||||
/// 出版物加载与分页、阅读位置恢复、加载状态管理、错误处理等生命周期操作。
|
||||
|
||||
extension RDEPUBReaderController {
|
||||
/// 应用阅读器视图配置,处理显示类型/翻页方向/横屏双页等变更并恢复位置
|
||||
|
||||
func applyReaderViewConfiguration() {
|
||||
let resolvedDirection = resolvedPageDirection()
|
||||
let presentationDidChange = readerView.currentDisplayType != configuration.displayType
|
||||
@@ -32,17 +23,14 @@ extension RDEPUBReaderController {
|
||||
}
|
||||
}
|
||||
|
||||
/// 启动初始加载流程(如果尚未加载)
|
||||
func startInitialLoadIfNeeded() {
|
||||
runtime.startInitialLoadIfNeeded()
|
||||
}
|
||||
|
||||
/// 加载 EPUB 出版物
|
||||
func loadPublication() {
|
||||
runtime.loadPublication()
|
||||
}
|
||||
|
||||
/// 应用已解析的出版物数据(解析器、出版物模型、书签、高亮等)
|
||||
func applyParsedPublication(
|
||||
parser: RDEPUBParser,
|
||||
publication: RDEPUBPublication,
|
||||
@@ -61,17 +49,14 @@ extension RDEPUBReaderController {
|
||||
)
|
||||
}
|
||||
|
||||
/// 对出版物执行分页计算
|
||||
func paginatePublication(restoreLocation: RDEPUBLocation?) {
|
||||
runtime.paginatePublication(restoreLocation: restoreLocation)
|
||||
}
|
||||
|
||||
/// 应用文本书籍数据并恢复阅读位置
|
||||
func applyTextBook(_ textBook: RDEPUBTextBook, restoreLocation: RDEPUBLocation?) {
|
||||
runtime.applyTextBook(textBook, restoreLocation: restoreLocation)
|
||||
}
|
||||
|
||||
/// 应用分页快照(页面列表与章节信息)
|
||||
func applyPaginationSnapshot(
|
||||
_ snapshot: (pages: [EPUBPage], chapters: [EPUBChapterInfo]),
|
||||
restoreLocation: RDEPUBLocation?
|
||||
@@ -79,17 +64,14 @@ extension RDEPUBReaderController {
|
||||
runtime.applyPaginationSnapshot(snapshot, restoreLocation: restoreLocation)
|
||||
}
|
||||
|
||||
/// 完成分页流程并恢复阅读位置
|
||||
func finishPagination(restoreLocation: RDEPUBLocation?) {
|
||||
runtime.finishPagination(restoreLocation: restoreLocation)
|
||||
}
|
||||
|
||||
/// 保留当前位置重新执行分页
|
||||
func repaginatePreservingCurrentLocation() {
|
||||
runtime.repaginatePreservingCurrentLocation()
|
||||
}
|
||||
|
||||
/// 恢复到指定阅读位置,返回是否成功
|
||||
@discardableResult
|
||||
func restoreReadingLocation(
|
||||
_ location: RDEPUBLocation,
|
||||
@@ -103,27 +85,22 @@ extension RDEPUBReaderController {
|
||||
)
|
||||
}
|
||||
|
||||
/// 获取当前可见页面的位置
|
||||
func currentVisibleLocation() -> RDEPUBLocation? {
|
||||
runtime.currentVisibleLocation()
|
||||
}
|
||||
|
||||
/// 获取持久化存储的阅读位置
|
||||
func persistenceLocation() -> RDEPUBLocation? {
|
||||
readerContext.persistenceLocation()
|
||||
}
|
||||
|
||||
/// 持久化当前阅读位置
|
||||
func persist(location: RDEPUBLocation) {
|
||||
readerContext.persist(location: location)
|
||||
}
|
||||
|
||||
/// 更新当前文本选区状态
|
||||
func updateCurrentSelection(_ selection: RDEPUBSelection?) {
|
||||
runtime.annotationCoordinator.updateCurrentSelection(selection)
|
||||
}
|
||||
|
||||
/// 将选区限定到指定 spine 范围内
|
||||
func scopedSelection(
|
||||
_ selection: RDEPUBSelection,
|
||||
relativeToSpineIndex spineIndex: Int?
|
||||
@@ -131,60 +108,49 @@ extension RDEPUBReaderController {
|
||||
runtime.annotationCoordinator.scopedSelection(selection, relativeToSpineIndex: spineIndex)
|
||||
}
|
||||
|
||||
/// 刷新可见内容并保留当前位置
|
||||
func refreshVisibleContentPreservingLocation() {
|
||||
runtime.refreshVisibleContentPreservingLocation()
|
||||
}
|
||||
|
||||
/// 重建外部文本书籍
|
||||
func rebuildExternalTextBook() {
|
||||
runtime.rebuildExternalTextBook()
|
||||
}
|
||||
|
||||
/// 更新阅读器 UI 装饰层(导航栏、工具栏等)
|
||||
func updateReaderChrome() {
|
||||
runtime.updateReaderChrome()
|
||||
}
|
||||
|
||||
/// 展示书签管理界面
|
||||
func presentBookmarksManager() {
|
||||
runtime.presentBookmarksManager()
|
||||
}
|
||||
|
||||
/// 展示高亮标注管理界面
|
||||
func presentHighlightsManager() {
|
||||
runtime.presentHighlightsManager()
|
||||
}
|
||||
|
||||
/// 展示标注创建界面
|
||||
func presentAnnotationCreation() {
|
||||
runtime.presentAnnotationCreation()
|
||||
}
|
||||
|
||||
/// 处理选区菜单操作(复制、标注、分享等)
|
||||
func handleSelectionMenuAction(_ action: RDEPUBAnnotationMenuAction, selection: RDEPUBSelection?) {
|
||||
runtime.handleSelectionMenuAction(action, selection: selection)
|
||||
}
|
||||
|
||||
/// 展示阅读设置界面
|
||||
func presentSettings() {
|
||||
runtime.presentSettings()
|
||||
}
|
||||
|
||||
/// 使用闭包更新阅读器配置
|
||||
func updateConfiguration(_ update: (inout RDEPUBReaderConfiguration) -> Void) {
|
||||
var nextConfiguration = configuration
|
||||
update(&nextConfiguration)
|
||||
configuration = nextConfiguration
|
||||
}
|
||||
|
||||
/// 设置屏幕亮度并持久化
|
||||
func setScreenBrightness(_ brightness: CGFloat) {
|
||||
currentBrightness = max(0, min(1, brightness))
|
||||
persistReaderSettingsIfNeeded()
|
||||
}
|
||||
|
||||
/// 持久化阅读器设置(亮度、配置等)
|
||||
func persistReaderSettingsIfNeeded() {
|
||||
let settings = RDEPUBReaderSettings.capture(
|
||||
configuration: configuration,
|
||||
@@ -193,7 +159,6 @@ extension RDEPUBReaderController {
|
||||
persistence?.saveReaderSettings(settings)
|
||||
}
|
||||
|
||||
/// 判断配置变更是否需要重新分页
|
||||
func requiresRepagination(
|
||||
from oldConfiguration: RDEPUBReaderConfiguration,
|
||||
to newConfiguration: RDEPUBReaderConfiguration
|
||||
@@ -210,7 +175,6 @@ extension RDEPUBReaderController {
|
||||
oldConfiguration.textRenderingEngine != newConfiguration.textRenderingEngine
|
||||
}
|
||||
|
||||
/// 判断配置变更是否需要刷新可见内容
|
||||
func requiresVisibleRefresh(
|
||||
from oldConfiguration: RDEPUBReaderConfiguration,
|
||||
to newConfiguration: RDEPUBReaderConfiguration
|
||||
@@ -220,17 +184,14 @@ extension RDEPUBReaderController {
|
||||
oldConfiguration.darkImageBlendRatio != newConfiguration.darkImageBlendRatio
|
||||
}
|
||||
|
||||
/// 展示目录界面
|
||||
func presentTableOfContents() {
|
||||
runtime.presentTableOfContents()
|
||||
}
|
||||
|
||||
/// 处理返回操作
|
||||
func handleBackAction() {
|
||||
runtime.handleBackAction()
|
||||
}
|
||||
|
||||
/// 处理错误:停止分页、隐藏加载指示器、显示错误信息并通知代理
|
||||
func handle(error: Error) {
|
||||
isRepaginating = false
|
||||
hideLoading()
|
||||
@@ -243,23 +204,19 @@ extension RDEPUBReaderController {
|
||||
delegate?.epubReader(self, didFailWithError: error)
|
||||
}
|
||||
|
||||
/// 显示加载指示器
|
||||
func showLoading() {
|
||||
errorLabel.isHidden = true
|
||||
loadingIndicator.startAnimating()
|
||||
}
|
||||
|
||||
/// 隐藏加载指示器
|
||||
func hideLoading() {
|
||||
loadingIndicator.stopAnimating()
|
||||
}
|
||||
|
||||
/// 获取当前视口签名(用于检测视口变化)
|
||||
func currentViewportSignature() -> RDEPUBViewportSignature? {
|
||||
runtime.currentViewportSignature()
|
||||
}
|
||||
|
||||
/// 检测并处理视口变化(旋转、尺寸变化等)
|
||||
func handleViewportChangeIfNeeded(
|
||||
reason: RDEPUBViewportChangeReason,
|
||||
viewportSignature: RDEPUBViewportSignature? = nil
|
||||
@@ -267,21 +224,17 @@ extension RDEPUBReaderController {
|
||||
runtime.handleViewportChangeIfNeeded(reason: reason, viewportSignature: viewportSignature)
|
||||
}
|
||||
|
||||
/// 获取指定页面的搜索结果展示状态
|
||||
func searchPresentation(for page: EPUBPage) -> RDEPUBSearchPresentation? {
|
||||
runtime.searchPresentation(for: page)
|
||||
}
|
||||
|
||||
/// 根据出版物阅读方向解析页面翻页方向
|
||||
private func resolvedPageDirection() -> RDReaderView.PageDirection {
|
||||
publication?.readingProgression == .rtl ? .rightToLeft : .leftToRight
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - 手势识别器代理
|
||||
|
||||
extension RDEPUBReaderController: UIGestureRecognizerDelegate {
|
||||
/// 手势识别器代理,始终返回 true 允许手势触发
|
||||
|
||||
public func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
|
||||
true
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user