185 lines
6.1 KiB
Swift
185 lines
6.1 KiB
Swift
import UIKit
|
||
|
||
// MARK: - 翻页显示模式
|
||
|
||
/// 阅读器翻页显示模式枚举
|
||
/// 用于持久化存储用户的翻页偏好设置,与 RDReaderView.DisplayType 相互转换
|
||
public enum RDEPUBReaderDisplayMode: String, Codable, Equatable {
|
||
/// 仿真翻页模式(纸张翻转效果)
|
||
case pageCurl
|
||
/// 水平滚动模式
|
||
case horizontalScroll
|
||
/// 垂直滚动模式
|
||
case verticalScroll
|
||
/// 水平覆盖式滚动模式(类似电子杂志翻页效果)
|
||
case horizontalCoverScroll
|
||
|
||
/// 从底层 DisplayType 转换为 UI 层的 DisplayMode
|
||
init(displayType: RDReaderView.DisplayType) {
|
||
switch displayType {
|
||
case .pageCurl:
|
||
self = .pageCurl
|
||
case .horizontalScroll:
|
||
self = .horizontalScroll
|
||
case .verticalScroll:
|
||
self = .verticalScroll
|
||
}
|
||
}
|
||
|
||
/// 转换为底层 RDReaderView 所需的 DisplayType
|
||
/// 注意:horizontalCoverScroll 会被映射为 horizontalScroll
|
||
var displayType: RDReaderView.DisplayType {
|
||
switch self {
|
||
case .pageCurl:
|
||
return .pageCurl
|
||
case .horizontalScroll, .horizontalCoverScroll:
|
||
return .horizontalScroll
|
||
case .verticalScroll:
|
||
return .verticalScroll
|
||
}
|
||
}
|
||
}
|
||
|
||
// MARK: - 主题预设
|
||
|
||
/// 阅读器主题预设枚举
|
||
/// 将 RDEPUBReaderTheme 映射为可序列化的枚举值,用于持久化存储和设置面板展示
|
||
public enum RDEPUBReaderThemePreset: String, Codable, CaseIterable, Equatable {
|
||
/// 浅色主题
|
||
case light
|
||
/// 黄色护眼主题
|
||
case yellow
|
||
/// 绿色护眼主题
|
||
case green
|
||
/// 粉色主题
|
||
case pink
|
||
/// 蓝色主题
|
||
case blue
|
||
/// 深色/夜间主题
|
||
case dark
|
||
|
||
/// 将预设枚举转换为主题配置实例
|
||
public var theme: RDEPUBReaderTheme {
|
||
switch self {
|
||
case .light:
|
||
return .light
|
||
case .yellow:
|
||
return .yellow
|
||
case .green:
|
||
return .green
|
||
case .pink:
|
||
return .pink
|
||
case .blue:
|
||
return .blue
|
||
case .dark:
|
||
return .dark
|
||
}
|
||
}
|
||
|
||
/// 从主题配置实例反向查找对应的预设枚举
|
||
/// 自定义主题(非内置预设)会返回 nil
|
||
public init?(theme: RDEPUBReaderTheme) {
|
||
switch theme {
|
||
case .light:
|
||
self = .light
|
||
case .yellow:
|
||
self = .yellow
|
||
case .green:
|
||
self = .green
|
||
case .pink:
|
||
self = .pink
|
||
case .blue:
|
||
self = .blue
|
||
case .dark:
|
||
self = .dark
|
||
default:
|
||
return nil
|
||
}
|
||
}
|
||
}
|
||
|
||
// MARK: - 阅读器用户设置
|
||
|
||
/// 阅读器的可持久化用户设置
|
||
/// 用于保存用户在设置面板中调整的阅读偏好(字号、行距、翻页模式、主题等)
|
||
/// 所有属性均为可选类型,只覆盖用户实际修改过的配置项
|
||
public struct RDEPUBReaderSettings: Codable, Equatable {
|
||
// MARK: 可调参数
|
||
|
||
/// 屏幕亮度(0.0 ~ 1.0),nil 表示使用系统亮度
|
||
public var brightness: CGFloat?
|
||
/// 用户选择的正文字号(pt),nil 表示使用默认值
|
||
public var fontSize: CGFloat?
|
||
/// 用户选择的行距倍数,nil 表示使用默认值
|
||
public var lineHeightMultiple: CGFloat?
|
||
/// 用户选择的栏数,nil 表示使用默认值
|
||
public var numberOfColumns: Int?
|
||
/// 用户选择的翻页模式,nil 表示使用默认值
|
||
public var displayMode: RDEPUBReaderDisplayMode?
|
||
/// 用户选择的主题预设,nil 表示使用默认值
|
||
public var themePreset: RDEPUBReaderThemePreset?
|
||
|
||
/// 初始化用户设置,所有参数默认为 nil
|
||
public init(
|
||
brightness: CGFloat? = nil,
|
||
fontSize: CGFloat? = nil,
|
||
lineHeightMultiple: CGFloat? = nil,
|
||
numberOfColumns: Int? = nil,
|
||
displayMode: RDEPUBReaderDisplayMode? = nil,
|
||
themePreset: RDEPUBReaderThemePreset? = nil
|
||
) {
|
||
self.brightness = brightness
|
||
self.fontSize = fontSize
|
||
self.lineHeightMultiple = lineHeightMultiple
|
||
self.numberOfColumns = numberOfColumns
|
||
self.displayMode = displayMode
|
||
self.themePreset = themePreset
|
||
}
|
||
|
||
/// 将用户设置覆盖到基础配置上,得到最终生效的阅读器配置
|
||
/// nil 属性不会覆盖基础配置的对应值
|
||
/// - Parameter configuration: 基础配置(通常来自 RDEPUBReaderConfiguration.default)
|
||
/// - Returns: 合并后的完整配置
|
||
public func applying(to configuration: RDEPUBReaderConfiguration) -> RDEPUBReaderConfiguration {
|
||
var resolvedConfiguration = configuration
|
||
|
||
if let fontSize {
|
||
resolvedConfiguration.fontSize = fontSize
|
||
}
|
||
if let lineHeightMultiple {
|
||
resolvedConfiguration.lineHeightMultiple = lineHeightMultiple
|
||
}
|
||
if let numberOfColumns {
|
||
resolvedConfiguration.numberOfColumns = max(1, numberOfColumns)
|
||
}
|
||
if let displayMode {
|
||
resolvedConfiguration.displayType = displayMode.displayType
|
||
}
|
||
if let themePreset {
|
||
resolvedConfiguration.theme = themePreset.theme
|
||
}
|
||
|
||
return resolvedConfiguration
|
||
}
|
||
|
||
/// 从当前配置和亮度值捕获一份完整的用户设置快照
|
||
/// 亮度值会被限制在 0.0 ~ 1.0 范围内
|
||
/// - Parameters:
|
||
/// - configuration: 当前生效的阅读器配置
|
||
/// - brightness: 当前屏幕亮度
|
||
/// - Returns: 完整的用户设置实例
|
||
public static func capture(
|
||
configuration: RDEPUBReaderConfiguration,
|
||
brightness: CGFloat
|
||
) -> RDEPUBReaderSettings {
|
||
RDEPUBReaderSettings(
|
||
brightness: max(0, min(1, brightness)),
|
||
fontSize: configuration.fontSize,
|
||
lineHeightMultiple: configuration.lineHeightMultiple,
|
||
numberOfColumns: configuration.numberOfColumns,
|
||
displayMode: RDEPUBReaderDisplayMode(displayType: configuration.displayType),
|
||
themePreset: RDEPUBReaderThemePreset(theme: configuration.theme)
|
||
)
|
||
}
|
||
}
|