源码注释: - 为 ~60 个 Swift 文件补充缺失的 doc comment(file header、类型、属性、方法) - 修正 4 处错误注释:翻页模式数量、搜索行为描述、手势识别器描述、悬空文档块 文档维护: - 删除重复文档:WXRead/读书EPUB阅读器实现架构.md(与微信读书版完全一致) - 合并重叠文档:阅读器规划.md → 阅读器功能开发计划.md(单一真值) - 修正过时内容:所有文档中"四种翻页模式"→"三种",移除 horizontalCoverScroll - 更新架构图:补齐 EPUBUI/ReaderController、Paging/、Typesetter/ 等子目录 - 更新 index.md 索引:新增开发计划和架构对比文档引用
83 lines
3.6 KiB
Swift
83 lines
3.6 KiB
Swift
//
|
||
// RDReaderView+ContentAccess.swift
|
||
// ReadViewSDK
|
||
//
|
||
// 文件职责:内容视图注册、复用和页面内容访问,提供类似 UITableView 的 register/dequeueReusable 机制。
|
||
//
|
||
|
||
import UIKit
|
||
|
||
/// 内容视图注册和复用扩展
|
||
/// 提供类似 UITableView 的 register/dequeueReusable 机制
|
||
extension RDReaderView {
|
||
/// 注册内容视图类型
|
||
public func register(contentView: UIView.Type, contentViewWithReuseIdentifier identifier: String) {
|
||
contentViews[identifier] = contentView
|
||
collectionView.register(RDReaderContentCell.self, forCellWithReuseIdentifier: identifier)
|
||
}
|
||
|
||
/// 获取可复用的内容视图
|
||
/// 优先从当前显示的 cell 中获取,其次创建新实例
|
||
public func dequeueReusableContentView(withReuseIdentifier identifier: String, for pageNum: Int) -> UIView {
|
||
if self.currentDisplayType != .pageCurl, let cell = self.collectionView.cellForItem(at: IndexPath(row: pageNum, section: 0)) as? RDReaderContentCell, let containerView = cell.containerView {
|
||
return containerView
|
||
}
|
||
let contentViewClass = contentViews[identifier]
|
||
assert(contentViewClass != nil, "请调用register(contentView:contentViewWithReuseIdentifier:)")
|
||
var contentView = contentViewClass!.init()
|
||
return contentView
|
||
}
|
||
|
||
/// 获取指定页码的内容视图
|
||
/// pageCurl 模式从 PageViewController 获取,滚动模式从 CollectionView cell 获取
|
||
public func pageContentView(pageNum: Int) -> UIView? {
|
||
if currentDisplayType == .pageCurl {
|
||
return (self.pageViewController.viewControllers?.first as? RDReaderPageChildViewController)?.contentView
|
||
} else {
|
||
let cell = collectionView.cellForItem(at: IndexPath(item: pageNum, section: 0)) as? RDReaderContentCell
|
||
return cell?.containerView
|
||
}
|
||
}
|
||
|
||
/// 返回当前阅读模式下单页内容容器的实际尺寸。
|
||
/// 优先使用已经显示出来的内容视图尺寸;若页面尚未装载,则回退到当前模式下的理论单页尺寸。
|
||
public func resolvedSinglePageSize(pageNum: Int? = nil) -> CGSize {
|
||
let targetPage = pageNum ?? (currentPage >= 0 ? currentPage : nil)
|
||
if let targetPage,
|
||
let contentView = pageContentView(pageNum: targetPage),
|
||
contentView.bounds.width > 0,
|
||
contentView.bounds.height > 0 {
|
||
return contentView.bounds.size
|
||
}
|
||
|
||
if currentDisplayType == .pageCurl {
|
||
if let childViewController = pageViewController.viewControllers?.first as? RDReaderPageChildViewController,
|
||
childViewController.view.bounds.width > 0,
|
||
childViewController.view.bounds.height > 0 {
|
||
return childViewController.view.bounds.size
|
||
}
|
||
if pageViewController.view.bounds.width > 0, pageViewController.view.bounds.height > 0 {
|
||
return pageViewController.view.bounds.size
|
||
}
|
||
return bounds.size
|
||
}
|
||
|
||
let containerBounds = collectionView.bounds.size == .zero ? bounds.size : collectionView.bounds.size
|
||
guard containerBounds.width > 0, containerBounds.height > 0 else {
|
||
return bounds.size
|
||
}
|
||
|
||
switch currentDisplayType {
|
||
case .horizontalScroll:
|
||
return CGSize(
|
||
width: containerBounds.width / CGFloat(max(pagesPerScreen, 1)),
|
||
height: containerBounds.height
|
||
)
|
||
case .verticalScroll:
|
||
return containerBounds
|
||
case .pageCurl:
|
||
return bounds.size
|
||
}
|
||
}
|
||
}
|