ReadViewSDK/Sources/RDPDFReaderView/Sources/RDPDFReaderHighlightOverlayView.swift
shenlei 1bde945d36 将 PDF 划线/注释交互完整下沉到 SDK 库
- RDPDFReaderPageView:完整页面视图移入 SDK(缩放画布、文字选择层、
  选区放大镜、无障碍视口),并内置与 EPUB 一致的两套系统编辑菜单:
  选区菜单(复制/划线/注释)、已有划线菜单(复制/注释|删除注释/删除划线)
- RDPDFReaderPageViewDelegate:宿主只通过代理做数据持久化与打开业务界面
- 修复划线命中判定:点击点先归一化再与标注比例坐标比较
- 修复 tappedHighlight 残留导致选区菜单项被错误过滤的问题
- 主题应用改为纯颜色入参,SDK 不依赖 EPUB 主题类型
- RDPDFReaderHighlightOverlayView 恢复为纯绘制层,点击交互统一由页面视图处理
- Demo 删除 PDFDemoPageView(约 290 行),改为实现代理回调

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-15 10:33:43 +09:00

68 lines
3.0 KiB
Swift
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import UIKit
/// SDK 线
/// 线 `RDPDFReaderPageView`
public final class RDPDFReaderHighlightOverlayView: UIView {
public var highlights: [RDPDFReaderHighlight] = [] { didSet { setNeedsDisplay() } }
public override init(frame: CGRect) {
super.init(frame: frame)
isOpaque = false
backgroundColor = .clear
isUserInteractionEnabled = false
}
public required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") }
public override func draw(_ rect: CGRect) {
guard let context = UIGraphicsGetCurrentContext() else { return }
context.clear(rect)
for highlight in highlights {
let color = UIColor(hexString: highlight.color)
context.setStrokeColor(color.cgColor)
context.setLineWidth(2)
let normalizedRect = highlight.normalizedRect
let underlineRect = CGRect(x: rect.width * normalizedRect.minX, y: rect.height * normalizedRect.minY, width: rect.width * normalizedRect.width, height: rect.height * normalizedRect.height)
let y = underlineRect.maxY - 1
context.move(to: CGPoint(x: underlineRect.minX, y: y))
context.addLine(to: CGPoint(x: underlineRect.maxX, y: y))
context.strokePath()
}
}
}
/// SDK
public final class RDPDFReaderSearchHighlightOverlayView: UIView {
public var matchRects: [CGRect] = [] { didSet { setNeedsDisplay() } }
public var activeIndex = -1 { didSet { setNeedsDisplay() } }
public override init(frame: CGRect) {
super.init(frame: frame)
isOpaque = false
backgroundColor = .clear
isUserInteractionEnabled = false
}
public required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") }
public override func draw(_ rect: CGRect) {
guard let context = UIGraphicsGetCurrentContext() else { return }
context.clear(rect)
for (index, matchRect) in matchRects.enumerated() {
let color = index == activeIndex
? UIColor(red: 0.14, green: 0.42, blue: 0.95, alpha: 0.34)
: UIColor(red: 0.21, green: 0.48, blue: 0.95, alpha: 0.16)
context.setFillColor(color.cgColor)
context.fill(CGRect(x: rect.width * matchRect.minX, y: rect.height * matchRect.minY, width: rect.width * matchRect.width, height: rect.height * matchRect.height))
}
}
}
private extension UIColor {
convenience init(hexString: String) {
let hex = hexString.trimmingCharacters(in: .whitespacesAndNewlines).replacingOccurrences(of: "#", with: "")
let value = UInt32(hex, radix: 16) ?? 0
self.init(red: CGFloat((value >> 16) & 0xFF) / 255, green: CGFloat((value >> 8) & 0xFF) / 255, blue: CGFloat(value & 0xFF) / 255, alpha: 1)
}
}