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