Files
ReadViewSDK/Sources/RDReaderView/EPUBUI/RDEPUBReaderController+PublicAPI.swift
T

177 lines
5.7 KiB
Swift

import UIKit
// MARK: - Public Reader Commands
extension RDEPUBReaderController {
/// 重新加载书籍,重置所有状态并重新解析 EPUB
public func reloadBook() {
runtime.reloadBook()
}
/// 跳转到指定阅读位置
/// - Parameter location: 目标阅读位置
public func go(to location: RDEPUBLocation) {
guard publication != nil else { return }
_ = runtime.go(to: location)
}
/// 跳转到指定页码
/// - Parameters:
/// - pageNumber: 目标页码(从 1 开始)
/// - animated: 是否动画过渡
/// - Returns: 是否跳转成功
@discardableResult
public func go(toPageNumber pageNumber: Int, animated: Bool = false) -> Bool {
runtime.go(toPageNumber: pageNumber, animated: animated)
}
/// 清除当前文本选中状态
public func clearSelection() {
runtime.clearSelection()
}
public func bookmark(withID id: String) -> RDEPUBBookmark? {
runtime.bookmark(withID: id)
}
public func highlight(withID id: String) -> RDEPUBHighlight? {
runtime.highlight(withID: id)
}
public func nativeTextSemanticSummary() -> String? {
guard let textBook,
let page = textBook.page(at: max(readerView.currentPage + 1, 1)) ?? textBook.pages.first else {
return nil
}
let metadata = page.metadata
var parts = [
"page \(page.absolutePageIndex + 1)",
"break \(metadata.breakReason.rawValue)",
metadata.blockKinds.isEmpty ? nil : "block kinds [\(metadata.blockKinds.map(\.rawValue).joined(separator: ","))]",
metadata.semanticHints.isEmpty ? nil : "hints [\(metadata.semanticHints.map(\.rawValue).joined(separator: ","))]",
metadata.attachmentPlacements.isEmpty ? nil : "placements [\(metadata.attachmentPlacements.map(\.rawValue).joined(separator: ","))]"
].compactMap { $0 }
if let firstDiagnostic = metadata.diagnostics.first {
parts.append(firstDiagnostic)
}
return parts.joined(separator: " · ")
}
/// 添加高亮标注,从当前选中文本或指定选区创建
/// - Parameters:
/// - selection: 文本选区,默认使用 currentSelection
/// - color: 高亮颜色(CSS 格式),默认黄色
/// - note: 可选批注文字
/// - Returns: 创建的高亮对象,重复时返回 nil
@discardableResult
public func addHighlight(
from selection: RDEPUBSelection? = nil,
color: String = "#F8E16C",
note: String? = nil
) -> RDEPUBHighlight? {
runtime.addHighlight(from: selection, color: color, note: note)
}
@discardableResult
public func addAnnotation(
from selection: RDEPUBSelection? = nil,
style: RDEPUBHighlightStyle,
color: String = "#F8E16C",
note: String? = nil
) -> RDEPUBHighlight? {
runtime.addAnnotation(from: selection, style: style, color: color, note: note)
}
@discardableResult
public func upsertHighlight(_ highlight: RDEPUBHighlight) -> RDEPUBHighlight? {
runtime.upsertHighlight(highlight)
}
@discardableResult
public func removeHighlight(id: String) -> RDEPUBHighlight? {
runtime.removeHighlight(id: id)
}
@discardableResult
public func updateHighlightNote(id: String, note: String?) -> RDEPUBHighlight? {
runtime.updateHighlightNote(id: id, note: note)
}
@discardableResult
public func go(toHighlightID id: String, animated: Bool = true) -> Bool {
runtime.go(toHighlightID: id, animated: animated)
}
public func removeAllHighlights() {
runtime.removeAllHighlights()
}
@discardableResult
public func go(toTableOfContentsItem item: EPUBTableOfContentsItem, animated: Bool = true) -> Bool {
go(toTableOfContentsHref: item.href, animated: animated)
}
@discardableResult
public func go(toTableOfContentsItem item: RDEPUBReaderTableOfContentsItem, animated: Bool = true) -> Bool {
go(toTableOfContentsHref: item.href, animated: animated)
}
@discardableResult
public func go(toTableOfContentsHref href: String, animated: Bool = true) -> Bool {
guard publication != nil else { return false }
let components = href.components(separatedBy: "#")
let baseHref = components.first ?? href
let fragment = components.count > 1 ? components[1] : nil
let location = RDEPUBLocation(
bookIdentifier: currentBookIdentifier,
href: baseHref,
progression: 0,
fragment: fragment
)
return restoreReadingLocation(location, animated: animated)
}
@discardableResult
public func addBookmark(note: String? = nil) -> RDEPUBBookmark? {
runtime.addBookmark(note: note)
}
@discardableResult
public func toggleBookmark(note: String? = nil) -> RDEPUBBookmark? {
runtime.toggleBookmark(note: note)
}
@discardableResult
public func removeBookmark(id: String) -> RDEPUBBookmark? {
runtime.removeBookmark(id: id)
}
@discardableResult
public func go(toBookmarkID id: String, animated: Bool = true) -> Bool {
runtime.go(toBookmarkID: id, animated: animated)
}
/// 执行全文搜索,自动跳转到第一个匹配项
/// - Parameter keyword: 搜索关键词,空字符串会清除搜索
public func search(keyword: String) {
runtime.search(keyword: keyword)
}
@discardableResult
public func searchNext() -> Bool {
runtime.searchNext()
}
@discardableResult
public func searchPrevious() -> Bool {
runtime.searchPrevious()
}
public func clearSearch() {
runtime.clearSearch()
}
}