Files
ReadViewSDK/Sources/RDReaderView/ReaderView/Paging/RDReaderSpreadResolver.swift
T
shenandshen 948004eed1 docs: 补充注释、修正过时文档、清理重复内容
源码注释:
- 为 ~60 个 Swift 文件补充缺失的 doc comment(file header、类型、属性、方法)
- 修正 4 处错误注释:翻页模式数量、搜索行为描述、手势识别器描述、悬空文档块

文档维护:
- 删除重复文档:WXRead/读书EPUB阅读器实现架构.md(与微信读书版完全一致)
- 合并重叠文档:阅读器规划.md → 阅读器功能开发计划.md(单一真值)
- 修正过时内容:所有文档中"四种翻页模式"→"三种",移除 horizontalCoverScroll
- 更新架构图:补齐 EPUBUI/ReaderController、Paging/、Typesetter/ 等子目录
- 更新 index.md 索引:新增开发计划和架构对比文档引用
2026-06-01 09:33:23 +08:00

88 lines
3.0 KiB
Swift

//
// RDReaderSpreadResolver.swift
// ReadViewSDK
//
// 文件职责:页面展开(spread)解析器,负责计算双页模式下的页面配对和翻页目标。
//
import Foundation
/// 页面展开解析器
/// 处理横屏双页模式下的页码配对逻辑,包括封面页独占、双页对齐、
/// 以及相邻页面跳转等计算。
struct RDReaderSpreadResolver {
/// 判断指定页码是否为全屏独占页面(如封面页在双页模式下独占一屏)
func isFullScreenPage(
_ pageNum: Int,
landscapeDualPageEnabled: Bool,
isLandscape: Bool,
coverPageIndex: Int?
) -> Bool {
guard landscapeDualPageEnabled, isLandscape, let coverIndex = coverPageIndex else { return false }
return pageNum == coverIndex
}
/// 计算指定页码在双页模式下的左右页配对,返回 (左页, 右页?)。
/// 封面页独占时单独处理,后续页面按两页一组配对。
func dualPagePair(
for pageNum: Int,
totalPages: Int,
coverPageIndex: Int?
) -> (left: Int, right: Int?) {
if let coverIndex = coverPageIndex {
if pageNum == coverIndex {
return (coverIndex, nil)
}
let adjustedIndex = pageNum - (coverIndex + 1)
let pairStart = coverIndex + 1 + (adjustedIndex / 2) * 2
let left = pairStart
let right = pairStart + 1 < totalPages ? pairStart + 1 : nil
return (left, right)
}
let left = (pageNum / 2) * 2
let right = left + 1 < totalPages ? left + 1 : nil
return (left, right)
}
/// 计算从指定页码出发的下一个(或上一个)双页展开的起始页码
func adjacentDualPage(
from pageNum: Int,
totalPages: Int,
coverPageIndex: Int?,
forward: Bool
) -> Int? {
let pair = dualPagePair(for: pageNum, totalPages: totalPages, coverPageIndex: coverPageIndex)
if forward {
let nextStart = (pair.right ?? pair.left) + 1
return nextStart < totalPages ? nextStart : nil
}
let prevEnd = pair.left - 1
guard prevEnd >= 0 else { return nil }
return dualPagePair(for: prevEnd, totalPages: totalPages, coverPageIndex: coverPageIndex).left
}
/// 计算下一页(或上一页)的页码,自动根据单页/双页模式选择合适的算法
func nextPage(
from currentPage: Int,
totalPages: Int,
pagesPerScreen: Int,
coverPageIndex: Int?,
forward: Bool
) -> Int? {
if pagesPerScreen > 1 {
return adjacentDualPage(
from: currentPage,
totalPages: totalPages,
coverPageIndex: coverPageIndex,
forward: forward
)
}
let target = currentPage + (forward ? 1 : -1)
guard target >= 0, target < totalPages else { return nil }
return target
}
}