SDK 化收尾: - 新增 RDPDFReaderView 本地 pod(阅读容器、成品控制器、划线/注释、画笔、 目录/设置面板、主题与持久化契约),Demo 精简为 PDFKit 页面提供者 + 持久化宿主 - Podfile/工程接入 RDPDFReaderView 与 SnapKit,示例书改用 PDF 阅读器示例文件 手机横屏单页竖滑修复: - cell 高度改为宽度适配后的纸张高度(sizeForItemAt + 宿主按页提供纵横比), 纵向超出一屏的内容由外层 collectionView 连续滚动承接,不再被裁掉 - 页面内部不再开启同向嵌套的兜底竖向拖动,修复外层滚动被吞、无法滚到下一页 - 修复 applyContentSize 先评估拖动开关后写 contentSize 的顺序缺陷 - 页码按视口中心命中 cell 计算,补 didEndDragging 兜底;旋转重锚点与 transitionToPage 改用真实布局位置 - 横竖屏同为竖滑时也重建 cell 并刷新全部可见页的适配配置 - 横屏单页点击不再跳页,只显隐工具栏;翻页交给连续竖滑 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
138 lines
5.1 KiB
Swift
138 lines
5.1 KiB
Swift
import UIKit
|
||
import SnapKit
|
||
|
||
final class RDEPUBReaderBottomToolView: RDEPUBReaderToolView, RDEPUBReaderBottomToolViewProtocol {
|
||
|
||
var onShowTableOfContents: (() -> Void)?
|
||
|
||
var onShowBookmarks: (() -> Void)?
|
||
|
||
var onShowHighlights: (() -> Void)?
|
||
|
||
@available(*, deprecated, message: "Use the text selection menu to create annotations.")
|
||
var onAddHighlight: (() -> Void)?
|
||
|
||
var onShowSettings: (() -> Void)?
|
||
|
||
private let stackView: UIStackView = {
|
||
let view = UIStackView()
|
||
view.axis = .horizontal
|
||
view.distribution = .fillEqually
|
||
view.alignment = .fill
|
||
view.spacing = 16
|
||
return view
|
||
}()
|
||
|
||
private let chapterButton = RDEPUBReaderTintButton(type: .system)
|
||
|
||
private let bookmarksButton = RDEPUBReaderTintButton(type: .system)
|
||
|
||
/// 标注列表入口:查看全书已有划线 / 注释
|
||
private let annotationListButton = RDEPUBReaderTintButton(type: .system)
|
||
|
||
private let settingsButton = RDEPUBReaderTintButton(type: .system)
|
||
|
||
override init(frame: CGRect) {
|
||
super.init(frame: frame)
|
||
accessibilityIdentifier = "epub.reader.bottomToolbar"
|
||
|
||
addSubview(stackView)
|
||
stackView.addArrangedSubview(chapterButton)
|
||
stackView.addArrangedSubview(bookmarksButton)
|
||
stackView.addArrangedSubview(annotationListButton)
|
||
stackView.addArrangedSubview(settingsButton)
|
||
|
||
stackView.snp.makeConstraints { make in
|
||
make.horizontalEdges.equalToSuperview().inset(16)
|
||
make.top.equalToSuperview()
|
||
make.bottom.equalTo(safeAreaLayoutGuide)
|
||
}
|
||
|
||
configureButton(chapterButton, systemName: "list.bullet", fallbackTitle: "目录")
|
||
configureButton(bookmarksButton, systemName: "bookmark", fallbackTitle: "书签")
|
||
configureButton(annotationListButton, systemName: "note.text", fallbackTitle: "标注")
|
||
configureButton(settingsButton, systemName: "textformat.size", fallbackTitle: "设置")
|
||
chapterButton.accessibilityIdentifier = "epub.reader.toc"
|
||
bookmarksButton.accessibilityIdentifier = "epub.reader.bookmarks"
|
||
annotationListButton.accessibilityIdentifier = "epub.reader.highlights"
|
||
settingsButton.accessibilityIdentifier = "epub.reader.settings"
|
||
|
||
[chapterButton, bookmarksButton, annotationListButton, settingsButton].forEach { button in
|
||
button.snp.makeConstraints { $0.height.greaterThanOrEqualTo(44) }
|
||
}
|
||
|
||
chapterButton.addTarget(self, action: #selector(chapterAction), for: .touchUpInside)
|
||
bookmarksButton.addTarget(self, action: #selector(bookmarksAction), for: .touchUpInside)
|
||
annotationListButton.addTarget(self, action: #selector(annotationListAction), for: .touchUpInside)
|
||
settingsButton.addTarget(self, action: #selector(settingsAction), for: .touchUpInside)
|
||
}
|
||
|
||
required init?(coder: NSCoder) {
|
||
fatalError("init(coder:) has not been implemented")
|
||
}
|
||
|
||
override func lineFrame(in bounds: CGRect) -> CGRect {
|
||
CGRect(x: 0, y: 0, width: bounds.width, height: 0.5)
|
||
}
|
||
|
||
override func apply(theme: RDEPUBReaderTheme) {
|
||
super.apply(theme: theme)
|
||
[chapterButton, bookmarksButton, annotationListButton, settingsButton].forEach { button in
|
||
button.tintColor = theme.toolControlTextColor
|
||
button.setTitleColor(theme.toolControlTextColor, for: .normal)
|
||
}
|
||
}
|
||
|
||
func setHighlightsEnabled(_ isEnabled: Bool) {
|
||
annotationListButton.isEnabled = isEnabled
|
||
annotationListButton.alpha = isEnabled ? 1 : 0.45
|
||
}
|
||
|
||
@available(*, deprecated, message: "Use the text selection menu to create annotations.")
|
||
func setAddHighlightEnabled(_ isEnabled: Bool) {
|
||
// The built-in toolbar no longer exposes this action. Keep the method so
|
||
// custom toolbar integrations compiled against previous SDKs remain valid.
|
||
}
|
||
|
||
func setBookmarksEnabled(_ isEnabled: Bool) {
|
||
bookmarksButton.isEnabled = isEnabled
|
||
bookmarksButton.alpha = isEnabled ? 1 : 0.45
|
||
}
|
||
|
||
func updateVisibility(
|
||
showsTableOfContents: Bool,
|
||
allowsHighlights: Bool,
|
||
showsSettingsPanel: Bool
|
||
) {
|
||
chapterButton.isHidden = !showsTableOfContents
|
||
bookmarksButton.isHidden = false
|
||
annotationListButton.isHidden = !allowsHighlights
|
||
settingsButton.isHidden = !showsSettingsPanel
|
||
}
|
||
|
||
private func configureButton(_ button: UIButton, systemName: String, fallbackTitle: String) {
|
||
button.titleLabel?.font = UIFont.systemFont(ofSize: 14, weight: .medium)
|
||
if #available(iOS 13.0, *), let image = UIImage(systemName: systemName) {
|
||
button.setImage(image.withRenderingMode(.alwaysTemplate), for: .normal)
|
||
} else {
|
||
button.setTitle(fallbackTitle, for: .normal)
|
||
}
|
||
}
|
||
|
||
@objc private func chapterAction() {
|
||
onShowTableOfContents?()
|
||
}
|
||
|
||
@objc private func bookmarksAction() {
|
||
onShowBookmarks?()
|
||
}
|
||
|
||
@objc private func annotationListAction() {
|
||
onShowHighlights?()
|
||
}
|
||
|
||
@objc private func settingsAction() {
|
||
onShowSettings?()
|
||
}
|
||
}
|