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