// // RDReaderPageChildViewController.swift // RDReaderDemo // // Created by yangsq on 2021/8/9. // // 文件职责:UIPageViewController 的子控制器,持有单页的内容视图和页码。 // 在 pageCurl 仿真翻页模式下,每个页面由一个 RDReaderPageChildViewController 管理, // 通过 contentContainerView 承载实际内容视图,并保持页码引用用于翻页状态追踪。 // // 架构位置:RDReaderView 四层架构中第三层的子控制器组件,被 UIPageViewController 使用。 // import UIKit /// 仿真翻页模式下的页面子控制器 /// 作为 UIPageViewController 的子控制器,每个实例管理一页内容。 /// 持有 ``contentView``(实际内容视图)和 ``pageNum``(页码标识), /// 通过 contentContainerView 将内容视图填满控制器视图。 class RDReaderPageChildViewController: UIViewController { /// 内容容器视图,作为 contentView 的父视图 private let contentContainerView = UIView() /// 实际内容视图 /// 设置时如果视图已加载,会自动重新安装到 contentContainerView 中 var contentView: UIView? { didSet { guard isViewLoaded else { return } installContentView() } } /// 该控制器管理的页码标识 var pageNum: Int = 0 /// 初始化方法 /// - Parameters: /// - contentView: 要显示的内容视图 /// - pageNum: 该页的页码(默认0) init(contentView: UIView?, pageNum: Int = 0) { self.contentView = contentView self.pageNum = pageNum super.init(nibName: nil, bundle: nil) } /// 加载视图时调用 /// 创建透明背景的根视图,添加 contentContainerView,并安装内容视图 override func loadView() { view = UIView() view.backgroundColor = .clear contentContainerView.frame = view.bounds contentContainerView.autoresizingMask = [.flexibleWidth, .flexibleHeight] contentContainerView.backgroundColor = .clear view.addSubview(contentContainerView) installContentView() } required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view. } /// 安装内容视图到 contentContainerView 中 /// 先移除 contentContainerView 中的所有子视图,再将 contentView 添加并填满 private func installContentView() { contentContainerView.subviews.forEach { $0.removeFromSuperview() } guard let contentView else { return } contentView.removeFromSuperview() contentView.frame = contentContainerView.bounds contentView.autoresizingMask = [.flexibleWidth, .flexibleHeight] contentContainerView.addSubview(contentView) } /* // MARK: - Navigation // In a storyboard-based application, you will often want to do a little preparation before navigation override func prepare(for segue: UIStoryboardSegue, sender: Any?) { // Get the new view controller using segue.destination. // Pass the selected object to the new view controller. } */ }