Files
ReadViewSDK/Sources/RDReaderView/ReaderView/RDReaderView+ContentAccess.swift
T

83 lines
3.6 KiB
Swift
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
//
// 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(contentViewcontentViewWithReuseIdentifier:)")
let 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
}
}
}