// RDEPUBNavigatorLayoutContext.swift // 导航器布局上下文 // 封装阅读器容器的布局参数:容器尺寸、每屏页数、安全区域、设备类型、 // 重排内容内边距等,供 Paginator 和渲染层使用。 import UIKit /// 导航器布局上下文,描述阅读器容器的布局参数 /// 在 Paginator 计算分页和 WebView 渲染时作为核心输入 public struct RDEPUBNavigatorLayoutContext: Equatable { /// 容器视图的总尺寸 public var containerSize: CGSize /// 每屏显示的页数(横屏双页模式为 2) public var pagesPerScreen: Int /// 安全区域内边距(刘海屏、Home Indicator 等) public var safeAreaInsets: UIEdgeInsets /// 用户界面设备类型(phone/pad) public var userInterfaceIdiom: UIUserInterfaceIdiom /// 重排模式下的内容内边距(上下左右留白) public var reflowableContentInsets: UIEdgeInsets public init( containerSize: CGSize, pagesPerScreen: Int = 1, safeAreaInsets: UIEdgeInsets = .zero, userInterfaceIdiom: UIUserInterfaceIdiom = .phone, reflowableContentInsets: UIEdgeInsets = UIEdgeInsets(top: 40, left: 16, bottom: 40, right: 16) ) { self.containerSize = containerSize self.pagesPerScreen = max(1, pagesPerScreen) self.safeAreaInsets = safeAreaInsets self.userInterfaceIdiom = userInterfaceIdiom self.reflowableContentInsets = reflowableContentInsets } /// 计算单页视口尺寸(双页模式下宽度除以 2) public var viewportSize: CGSize { let width: CGFloat if pagesPerScreen > 1 { width = containerSize.width / CGFloat(pagesPerScreen) } else { width = containerSize.width } return CGSize(width: width, height: containerSize.height) } /// 固定版式模式下的内容内边距(仅手机端使用安全区域,Pad 端归零;左右取较大值对称) public var fixedContentInset: UIEdgeInsets { var insets = safeAreaInsets if userInterfaceIdiom != .phone { insets = .zero } let horizontalInsets = max(insets.left, insets.right) insets.left = horizontalInsets insets.right = horizontalInsets return insets } }