import UIKit /// 朝向锁定支持。 /// /// 依据 `publication.metadata.orientation`(来源 OPF rendition:orientation, /// 或兜底的 iBooks display-options)返回受限的支持朝向,并在书籍打开后主动请求转向。 /// 未声明朝向(nil / .auto)时不干预,跟随系统与容器。 /// /// 注意:`supportedInterfaceOrientations` 只有当阅读器是当前决定朝向的控制器时才生效 /// (通常需宿主保证它被 present 或位于导航栈顶;若被包在自定义容器里,容器需转发该值)。 extension RDEPUBReaderController { /// 由 EPUB 元数据推导的受限支持朝向;nil = 不限制(跟随系统) var epubSupportedOrientationMask: UIInterfaceOrientationMask? { switch publication?.metadata.orientation { case .portrait: return .portrait case .landscape: return .landscape case .auto, .none: return nil } } public override var supportedInterfaceOrientations: UIInterfaceOrientationMask { epubSupportedOrientationMask ?? super.supportedInterfaceOrientations } public override var shouldAutorotate: Bool { // 已锁定单一朝向时不自动旋转 epubSupportedOrientationMask == nil } /// 打开书籍后按元数据主动转向(iOS 16+ 用 requestGeometryUpdate,旧系统回退到刷新支持朝向)。 /// 由加载完成流程调用。 func applyOrientationLockIfNeeded() { guard let mask = epubSupportedOrientationMask else { return } if #available(iOS 16.0, *) { setNeedsUpdateOfSupportedInterfaceOrientations() guard let scene = view.window?.windowScene else { return } scene.requestGeometryUpdate(.iOS(interfaceOrientations: mask)) { _ in } } else { let target: UIInterfaceOrientation = (mask == .landscape) ? .landscapeRight : .portrait UIDevice.current.setValue(target.rawValue, forKey: "orientation") UIViewController.attemptRotationToDeviceOrientation() } } }