- 新增 RDEPUBResourceDataProvider 解密钩子协议 + 访问登记表,收敛章节 HTML/ 图片/内联 CSS/脚注/封面/图片查看器/正文取图等读取点,scheme handler 对加密书 禁用流式分支;新增 RDEPUBDecryptingImageAttachment 解密 DTCoreText 图片附件; RDEPUBReaderDependencies.live(resourceDataProvider:) 便捷注入。明文书零影响。 - 试读墙:configuration.trialPolicy + delegate epubReaderTrialWallView/ DidReachTrialWall,UI 由宿主提供(RDEPUBReaderController+Trial)。 - 工具栏定制:RDEPUBReaderTop/BottomToolViewProtocol 协议 + dependencies 工厂注入, 内置栏已 conform,configureTopToolView 改协议类型。 - 朝向锁定:RDEPUBMetadata.orientation(OPF rendition:orientation 主, iBooks display-options 兜底)+ RDEPUBReaderController+Orientation 重写支持朝向、 打开后主动转向。 注:RDEPUBReaderController+LocationResolution / PaginationCoordinator 为本次改动前 即存在的工作区修改,一并纳入。 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
49 lines
2.1 KiB
Swift
49 lines
2.1 KiB
Swift
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()
|
||
}
|
||
}
|
||
}
|