From 1c6108061caf853b8826de25744dd0a5e45d60d5 Mon Sep 17 00:00:00 2001 From: shen <> Date: Mon, 1 Jun 2026 21:29:41 +0800 Subject: [PATCH] feat: improve native text selection and annotation actions --- .../UserInterfaceState.xcuserstate | Bin 102806 -> 113570 bytes .../ReaderUITests/ReaderAnnotationTests.swift | 4 +- ...PUBReaderController+ContentDelegates.swift | 8 + .../RDEPUBReaderAnnotationCoordinator.swift | 22 ++ .../RDEPUBReaderRuntime.swift | 4 + .../RDEPUBPageInteractionController.swift | 22 +- .../TextPage/RDEPUBTextContentView.swift | 324 ++++++++++-------- .../RDEPUBTextSelectionController.swift | 191 +++++++---- 8 files changed, 359 insertions(+), 216 deletions(-) diff --git a/ReadViewDemo/ReadViewDemo.xcworkspace/xcuserdata/shen.xcuserdatad/UserInterfaceState.xcuserstate b/ReadViewDemo/ReadViewDemo.xcworkspace/xcuserdata/shen.xcuserdatad/UserInterfaceState.xcuserstate index 904f89cf38b27f85dabfb257ef78eaf7b8e68ad4..71507a1c8df619eeb9be201ca5dd4daaa2292981 100644 GIT binary patch literal 113570 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 M`TzbC(y#Xa0KpF diff --git a/ReadViewDemo/ReadViewDemoUITests/ReaderUITests/ReaderAnnotationTests.swift b/ReadViewDemo/ReadViewDemoUITests/ReaderUITests/ReaderAnnotationTests.swift index 0018b1e..c7c213e 100644 --- a/ReadViewDemo/ReadViewDemoUITests/ReaderUITests/ReaderAnnotationTests.swift +++ b/ReadViewDemo/ReadViewDemoUITests/ReaderUITests/ReaderAnnotationTests.swift @@ -11,7 +11,7 @@ final class ReaderAnnotationTests: XCTestCase { app.launchAndOpenSampleBook(pageNumber: 2) app.waitForReader() - let content = app.textViews[IDs.readerSelectionText].firstMatch + let content = app.otherElements[IDs.readerSelectionText].firstMatch XCTAssertTrue(content.waitForExistence(timeout: 5), "阅读内容区域未出现") let start = content.coordinate(withNormalizedOffset: CGVector(dx: 0.35, dy: 0.42)) @@ -37,7 +37,7 @@ final class ReaderAnnotationTests: XCTestCase { app.launchAndOpenSampleBook(pageNumber: 2) app.waitForReader() - let content = app.textViews[IDs.readerSelectionText].firstMatch + let content = app.otherElements[IDs.readerSelectionText].firstMatch XCTAssertTrue(content.waitForExistence(timeout: 5), "阅读内容区域未出现") let start = content.coordinate(withNormalizedOffset: CGVector(dx: 0.35, dy: 0.42)) diff --git a/Sources/RDReaderView/EPUBUI/RDEPUBReaderController+ContentDelegates.swift b/Sources/RDReaderView/EPUBUI/RDEPUBReaderController+ContentDelegates.swift index 4372ff0..2eb1c96 100644 --- a/Sources/RDReaderView/EPUBUI/RDEPUBReaderController+ContentDelegates.swift +++ b/Sources/RDReaderView/EPUBUI/RDEPUBReaderController+ContentDelegates.swift @@ -96,6 +96,14 @@ extension RDEPUBReaderController: RDEPUBTextContentViewDelegate { contentView.clearSelection() } + func textContentView( + _ contentView: RDEPUBTextContentView, + didRequestHighlightActions highlight: RDEPUBHighlight, + sourceRect: CGRect + ) { + runtime.presentHighlightActions(for: highlight, sourceView: contentView, sourceRect: sourceRect) + } + /// 根据 EPUB 位置计算对应的页码 func pageNumber(for location: RDEPUBLocation) -> Int? { diff --git a/Sources/RDReaderView/EPUBUI/ReaderController/RDEPUBReaderAnnotationCoordinator.swift b/Sources/RDReaderView/EPUBUI/ReaderController/RDEPUBReaderAnnotationCoordinator.swift index fa1d27c..ea12b6c 100644 --- a/Sources/RDReaderView/EPUBUI/ReaderController/RDEPUBReaderAnnotationCoordinator.swift +++ b/Sources/RDReaderView/EPUBUI/ReaderController/RDEPUBReaderAnnotationCoordinator.swift @@ -225,6 +225,28 @@ final class RDEPUBReaderAnnotationCoordinator { presentAnnotationActionSheet(for: currentSelection) } + /// 弹出已有高亮/批注的操作菜单。 + func presentHighlightActions(for highlight: RDEPUBHighlight, sourceView: UIView, sourceRect: CGRect) { + guard let controller else { return } + let alert = UIAlertController(title: "标注操作", message: highlight.text, preferredStyle: .actionSheet) + alert.addAction(UIAlertAction(title: "删除高亮", style: .destructive) { [weak self] _ in + _ = self?.removeHighlight(id: highlight.id) + }) + if highlight.hasNote { + alert.addAction(UIAlertAction(title: "删除批注", style: .destructive) { [weak self] _ in + _ = self?.updateHighlightNote(id: highlight.id, note: nil) + }) + } + alert.addAction(UIAlertAction(title: "取消", style: .cancel)) + + if let popover = alert.popoverPresentationController { + popover.sourceView = sourceView + popover.sourceRect = sourceRect + } + + controller.present(alert, animated: true) + } + /// 处理文本选中后的菜单操作:复制、高亮、批注。 func handleSelectionMenuAction(_ action: RDEPUBAnnotationMenuAction, selection: RDEPUBSelection?) { guard let selection else { return } diff --git a/Sources/RDReaderView/EPUBUI/ReaderController/RDEPUBReaderRuntime.swift b/Sources/RDReaderView/EPUBUI/ReaderController/RDEPUBReaderRuntime.swift index bb5cf20..64bef98 100644 --- a/Sources/RDReaderView/EPUBUI/ReaderController/RDEPUBReaderRuntime.swift +++ b/Sources/RDReaderView/EPUBUI/ReaderController/RDEPUBReaderRuntime.swift @@ -182,6 +182,10 @@ final class RDEPUBReaderRuntime { annotationCoordinator.presentAnnotationCreation() } + func presentHighlightActions(for highlight: RDEPUBHighlight, sourceView: UIView, sourceRect: CGRect) { + annotationCoordinator.presentHighlightActions(for: highlight, sourceView: sourceView, sourceRect: sourceRect) + } + func handleSelectionMenuAction(_ action: RDEPUBAnnotationMenuAction, selection: RDEPUBSelection?) { annotationCoordinator.handleSelectionMenuAction(action, selection: selection) } diff --git a/Sources/RDReaderView/EPUBUI/TextPage/RDEPUBPageInteractionController.swift b/Sources/RDReaderView/EPUBUI/TextPage/RDEPUBPageInteractionController.swift index 4dc274d..4008522 100644 --- a/Sources/RDReaderView/EPUBUI/TextPage/RDEPUBPageInteractionController.swift +++ b/Sources/RDReaderView/EPUBUI/TextPage/RDEPUBPageInteractionController.swift @@ -53,7 +53,11 @@ final class RDEPUBPageInteractionController { ) let idx = dtLine.stringIndex(forPosition: relativePoint) guard idx != NSNotFound, idx >= 0 else { return nil } - return normalizedIndex(idx, lineRange: line.stringRange, pageRange: snapshot.pageContentRange) + return normalizedIndex( + idx + pageOffset(for: snapshot), + lineRange: line.stringRange, + pageRange: snapshot.pageContentRange + ) #else return nil #endif @@ -81,9 +85,10 @@ final class RDEPUBPageInteractionController { #if canImport(DTCoreText) guard let dtLine = dtLineContaining(range: line.stringRange) else { continue } - let startX = dtLine.offset(forStringIndex: overlap.location) + let pageOffset = pageOffset(for: snapshot) + let startX = dtLine.offset(forStringIndex: overlap.location - pageOffset) let endIdx = overlap.location + overlap.length - let endX = dtLine.offset(forStringIndex: endIdx) + let endX = dtLine.offset(forStringIndex: endIdx - pageOffset) #else let startX: CGFloat = 0 let endX: CGFloat = line.frame.width @@ -141,7 +146,7 @@ final class RDEPUBPageInteractionController { #if canImport(DTCoreText) guard let dtLine = dtLineContaining(range: line.stringRange) else { return nil } - let offsetX = dtLine.offset(forStringIndex: index) + let offsetX = dtLine.offset(forStringIndex: index - pageOffset(for: snapshot)) #else let offsetX: CGFloat = 0 #endif @@ -192,11 +197,16 @@ final class RDEPUBPageInteractionController { #if canImport(DTCoreText) private func dtLineContaining(range: NSRange) -> DTCoreTextLayoutLine? { - guard let dtLayoutFrame else { return nil } - return dtLayoutFrame.lineContaining(UInt(range.location)) + guard let dtLayoutFrame, let snapshot else { return nil } + let localLocation = max(range.location - pageOffset(for: snapshot), 0) + return dtLayoutFrame.lineContaining(UInt(localLocation)) } #endif + private func pageOffset(for snapshot: RDEPUBPageLayoutSnapshot) -> Int { + snapshot.page.pageStartOffset + } + private func mergeAdjacentRects(_ rects: [CGRect]) -> [CGRect] { guard rects.count > 1 else { return rects } diff --git a/Sources/RDReaderView/EPUBUI/TextPage/RDEPUBTextContentView.swift b/Sources/RDReaderView/EPUBUI/TextPage/RDEPUBTextContentView.swift index 3595caa..e722fd3 100644 --- a/Sources/RDReaderView/EPUBUI/TextPage/RDEPUBTextContentView.swift +++ b/Sources/RDReaderView/EPUBUI/TextPage/RDEPUBTextContentView.swift @@ -14,13 +14,17 @@ protocol RDEPUBTextContentViewDelegate: AnyObject { didRequestSelectionAction action: RDEPUBAnnotationMenuAction, selection: RDEPUBSelection? ) + func textContentView( + _ contentView: RDEPUBTextContentView, + didRequestHighlightActions highlight: RDEPUBHighlight, + sourceRect: CGRect + ) } // MARK: - 文本内容视图 /// EPUB 流式排版的文本内容视图 -/// 对齐 WXRead 架构:高亮通过 NSAttributedString 自定义属性注入,在统一 drawRect 中绘制。 -/// 保留 UITextView 用于 XCUITest 兼容和系统级文本选择。 +/// 对齐 WXRead 架构:选区和高亮共享 CoreText 命中测试与 drawRect 绘制结果。 final class RDEPUBTextContentView: UIView, UIGestureRecognizerDelegate { private static let darkAdjustedImageCache = NSCache() @@ -28,6 +32,7 @@ final class RDEPUBTextContentView: UIView, UIGestureRecognizerDelegate { private var currentPage: RDEPUBTextPage? private var currentSelection: RDEPUBSelection? private var menuSelection: RDEPUBSelection? + private var currentHighlights: [RDEPUBHighlight] = [] weak var delegate: RDEPUBTextContentViewDelegate? #if canImport(DTCoreText) @@ -55,19 +60,6 @@ final class RDEPUBTextContentView: UIView, UIGestureRecognizerDelegate { return view }() - /// 保留 UITextView 用于系统文本选择和 XCUITest 兼容 - private let textView: UITextView = { - let view = UITextView() - view.isEditable = false - view.isScrollEnabled = false - view.isSelectable = true - view.backgroundColor = .clear - view.accessibilityIdentifier = "epub.reader.selection.text" - view.textContainerInset = .zero - view.textContainer.lineFragmentPadding = 0 - return view - }() - private let coverImageView: UIImageView = { let view = UIImageView() view.contentMode = .scaleAspectFit @@ -81,25 +73,24 @@ final class RDEPUBTextContentView: UIView, UIGestureRecognizerDelegate { return label }() - // MARK: - Selection Action Bar + private lazy var longPressGestureRecognizer: UILongPressGestureRecognizer = { + let gesture = UILongPressGestureRecognizer(target: self, action: #selector(handleLongPress(_:))) + gesture.minimumPressDuration = 0.5 + gesture.delegate = self + return gesture + }() - private lazy var selectionActionBar: UIStackView = { - let stack = UIStackView(arrangedSubviews: [ - selectionMenuButton(title: "拷贝", menuAction: .copy), - selectionMenuButton(title: "高亮", menuAction: .highlight), - selectionMenuButton(title: "批注", menuAction: .annotate) - ]) - stack.axis = .horizontal - stack.alignment = .fill - stack.distribution = .fillEqually - stack.spacing = 1 - stack.backgroundColor = UIColor(white: 0.12, alpha: 0.96) - stack.layer.cornerRadius = 10 - stack.layer.masksToBounds = true - stack.layer.zPosition = 100 - stack.isHidden = true - stack.accessibilityIdentifier = "epub.reader.selection.menu" - return stack + private lazy var panGestureRecognizer: UIPanGestureRecognizer = { + let gesture = UIPanGestureRecognizer(target: self, action: #selector(handlePan(_:))) + gesture.isEnabled = false + gesture.delegate = self + return gesture + }() + + private lazy var tapGestureRecognizer: UITapGestureRecognizer = { + let gesture = UITapGestureRecognizer(target: self, action: #selector(handleTap(_:))) + gesture.delegate = self + return gesture }() // MARK: - Init @@ -113,19 +104,19 @@ final class RDEPUBTextContentView: UIView, UIGestureRecognizerDelegate { addSubview(coreTextContentView) #endif addSubview(overlayView) - addSubview(textView) addSubview(pageNumberLabel) - addSubview(selectionActionBar) + addGestureRecognizer(longPressGestureRecognizer) + addGestureRecognizer(panGestureRecognizer) + addGestureRecognizer(tapGestureRecognizer) + tapGestureRecognizer.require(toFail: longPressGestureRecognizer) - textView.delegate = selectionController selectionController.onSelectionChanged = { [weak self] selection in guard let self else { return } self.currentSelection = selection if let selection { self.menuSelection = selection - self.showSelectionActionBarIfNeeded() } else { - self.hideSelectionActionBar() + self.hideSelectionMenu() } self.delegate?.textContentView(self, didChangeSelection: selection) } @@ -169,7 +160,6 @@ final class RDEPUBTextContentView: UIView, UIGestureRecognizerDelegate { updateCoreTextLayoutFrameIfNeeded() #endif overlayView.frame = bounds.inset(by: contentInsets) - textView.frame = bounds.inset(by: contentInsets) coverImageView.frame = bounds.inset(by: contentInsets) let labelSize = pageNumberLabel.sizeThatFits(CGSize(width: bounds.width, height: 20)) @@ -179,7 +169,6 @@ final class RDEPUBTextContentView: UIView, UIGestureRecognizerDelegate { width: labelSize.width, height: labelSize.height ) - updateSelectionActionBarFrame() } // MARK: - Configure @@ -195,7 +184,8 @@ final class RDEPUBTextContentView: UIView, UIGestureRecognizerDelegate { currentPage = page currentSelection = nil menuSelection = nil - selectionController.clearSelection() + currentHighlights = highlights + selectionController.clearSelection(renderView: coreTextRenderView) contentInsets = configuration.reflowableContentInsets backgroundColor = configuration.theme.contentBackgroundColor pageNumberLabel.textColor = configuration.theme.contentTextColor @@ -207,10 +197,7 @@ final class RDEPUBTextContentView: UIView, UIGestureRecognizerDelegate { coreTextContentView.layoutFrame = nil coreTextDisplayContent = nil coreTextDisplayRange = nil - textView.isHidden = true - textView.isUserInteractionEnabled = false #endif - textView.attributedText = nil delegate?.textContentView(self, didChangeSelection: nil) setNeedsLayout() return @@ -234,14 +221,10 @@ final class RDEPUBTextContentView: UIView, UIGestureRecognizerDelegate { applyHighlightsToContent(displayContent, highlights: highlights, page: page) coreTextContentView.isHidden = false coreTextContentView.backgroundColor = .clear + coreTextContentView.accessibilityIdentifier = "epub.reader.selection.text" coreTextDisplayContent = displayContent coreTextDisplayRange = NSRange(location: 0, length: displayContent.length) coreTextContentView.attributedDisplayContent = displayContent - textView.isHidden = false - textView.isUserInteractionEnabled = true - textView.tintColor = configuration.theme.toolControlTextColor - textView.attributedText = selectionProxyContent(from: displayContent) - textView.selectedRange = NSRange(location: 0, length: 0) updateCoreTextLayoutFrameIfNeeded() #else let selectionContent = normalizedPageContent(from: page) @@ -253,23 +236,18 @@ final class RDEPUBTextContentView: UIView, UIGestureRecognizerDelegate { ) overlayView.applyHighlights(highlights, to: selectionContent, page: page, contentBaseOffset: page.pageStartOffset) overlayView.applySearchHighlights(to: selectionContent, page: page, searchState: searchState, contentBaseOffset: page.pageStartOffset) - textView.isHidden = false - textView.isUserInteractionEnabled = true - textView.tintColor = configuration.theme.toolControlTextColor - textView.attributedText = selectionProxyContent(from: selectionContent) - textView.selectedRange = NSRange(location: 0, length: 0) #endif overlayView.configure(page: page, selectionColor: overlayView.selectionColor, snapshot: interactionController.snapshot) #if canImport(DTCoreText) backgroundOverlayView.configure(page: page, selectionColor: overlayView.selectionColor, snapshot: interactionController.snapshot) - // 高亮/下划线已通过 attributed string 自定义属性注入,由 renderView 在 draw(_:) 中绘制 - let (_, fgDecorations) = overlayView.buildDecorations( + let (bgDecorations, fgDecorations) = overlayView.buildDecorations( page: page, highlights: [], searchState: searchState, interactionController: interactionController ) + backgroundOverlayView.applyDecorations(bgDecorations) overlayView.applyDecorations(fgDecorations) #endif @@ -280,8 +258,8 @@ final class RDEPUBTextContentView: UIView, UIGestureRecognizerDelegate { func clearSelection() { currentSelection = nil menuSelection = nil - selectionController.clearSelection() - textView.selectedRange = NSRange(location: 0, length: 0) + panGestureRecognizer.isEnabled = false + selectionController.clearSelection(renderView: coreTextRenderView) overlayView.clearSelection() backgroundOverlayView.clearSelection() UIMenuController.shared.setMenuVisible(false, animated: true) @@ -293,59 +271,7 @@ final class RDEPUBTextContentView: UIView, UIGestureRecognizerDelegate { let selection = currentSelection ?? menuSelection delegate?.textContentView(self, didRequestSelectionAction: action, selection: selection) menuSelection = nil - hideSelectionActionBar() - } - - private func selectionMenuButton(title: String, menuAction: RDEPUBAnnotationMenuAction) -> UIButton { - let button = UIButton(type: .system) - button.setTitle(title, for: .normal) - button.setTitleColor(.white, for: .normal) - button.titleLabel?.font = UIFont.systemFont(ofSize: 15, weight: .medium) - button.contentEdgeInsets = UIEdgeInsets(top: 10, left: 14, bottom: 10, right: 14) - button.backgroundColor = .clear - button.accessibilityLabel = title - button.accessibilityIdentifier = "epub.reader.selection.\(title)" - button.addAction( - UIAction { [weak self] _ in - self?.performSelectionAction(menuAction) - }, - for: .touchUpInside - ) - return button - } - - private func showSelectionActionBarIfNeeded() { - guard textView.selectedRange.length > 0, - let textRange = textView.selectedTextRange else { return } - let rect = textView.firstRect(for: textRange) - guard !rect.isNull, !rect.isEmpty else { return } - selectionActionBar.isHidden = false - updateSelectionActionBarFrame() - bringSubviewToFront(selectionActionBar) - } - - private func hideSelectionActionBar() { - selectionActionBar.isHidden = true - } - - private func updateSelectionActionBarFrame() { - guard !selectionActionBar.isHidden, - let textRange = textView.selectedTextRange else { return } - let rect = textView.firstRect(for: textRange) - guard !rect.isNull, !rect.isEmpty else { return } - let targetRect = convert(rect, from: textView) - - let fittingSize = selectionActionBar.systemLayoutSizeFitting(UIView.layoutFittingCompressedSize) - let width = max(fittingSize.width, 168) - let height = max(fittingSize.height, 42) - let horizontalPadding: CGFloat = 12 - let x = min( - max(targetRect.midX - width / 2, horizontalPadding), - max(horizontalPadding, bounds.width - width - horizontalPadding) - ) - let preferredY = targetRect.minY - height - 8 - let y = preferredY >= 8 ? preferredY : min(targetRect.maxY + 8, bounds.height - height - 8) - selectionActionBar.frame = CGRect(x: x, y: max(8, y), width: width, height: height) + hideSelectionMenu() } // MARK: - Cover Image @@ -364,10 +290,7 @@ final class RDEPUBTextContentView: UIView, UIGestureRecognizerDelegate { coreTextContentView.layoutFrame = nil coreTextDisplayContent = nil coreTextDisplayRange = nil - textView.isHidden = true - textView.isUserInteractionEnabled = false #endif - textView.attributedText = nil return true } @@ -506,33 +429,6 @@ final class RDEPUBTextContentView: UIView, UIGestureRecognizerDelegate { } } - // MARK: - Selection Proxy Content - - private func selectionProxyContent(from content: NSAttributedString) -> NSAttributedString { - let proxy = NSMutableAttributedString(attributedString: content) - let fullRange = NSRange(location: 0, length: proxy.length) - proxy.removeAttribute(.backgroundColor, range: fullRange) - proxy.addAttribute(.foregroundColor, value: UIColor.clear, range: fullRange) - - var attachmentRanges: [NSRange] = [] - proxy.enumerateAttribute(.attachment, in: fullRange) { value, range, _ in - guard value != nil else { return } - attachmentRanges.append(range) - } - - for range in attachmentRanges.reversed() { - let replacement = NSAttributedString( - string: String(repeating: " ", count: max(range.length, 1)), - attributes: [ - .font: proxy.attribute(.font, at: max(range.location - 1, 0), effectiveRange: nil) as Any, - .foregroundColor: UIColor.clear - ] - ) - proxy.replaceCharacters(in: range, with: replacement) - } - return proxy - } - // MARK: - Content Normalization private func normalizedPageContent(from page: RDEPUBTextPage) -> NSMutableAttributedString { @@ -588,6 +484,152 @@ final class RDEPUBTextContentView: UIView, UIGestureRecognizerDelegate { backgroundOverlayView.updateSnapshot(interactionController.snapshot) } #endif + + // MARK: - Gestures + + @objc private func handleLongPress(_ gesture: UILongPressGestureRecognizer) { +#if canImport(DTCoreText) + selectionController.handleLongPress( + gesture, + renderView: coreTextRenderView, + interactionController: interactionController + ) + switch gesture.state { + case .began: + panGestureRecognizer.isEnabled = true + case .ended: + panGestureRecognizer.isEnabled = false + showSelectionMenuIfNeeded() + case .cancelled, .failed: + panGestureRecognizer.isEnabled = false + default: + break + } +#endif + } + + @objc private func handlePan(_ gesture: UIPanGestureRecognizer) { +#if canImport(DTCoreText) + selectionController.handlePan( + gesture, + renderView: coreTextRenderView, + interactionController: interactionController + ) + switch gesture.state { + case .ended: + panGestureRecognizer.isEnabled = false + showSelectionMenuIfNeeded() + case .cancelled, .failed: + panGestureRecognizer.isEnabled = false + default: + break + } +#endif + } + + @objc private func handleTap(_ gesture: UITapGestureRecognizer) { + let point = gesture.location(in: overlayView) + if currentSelection != nil { + clearSelection() + return + } + guard let highlight = highlight(at: point), + let sourceRect = highlightSourceRect(for: highlight, fallbackPoint: point) else { + return + } + delegate?.textContentView(self, didRequestHighlightActions: highlight, sourceRect: sourceRect) + } + + private func showSelectionMenuIfNeeded() { + guard currentSelection != nil, + let targetRect = selectionController.menuAnchorRect(interactionController: interactionController), + !targetRect.isEmpty else { + return + } + becomeFirstResponder() + let menuController = UIMenuController.shared + menuController.menuItems = [ + UIMenuItem(title: "拷贝", action: #selector(rd_copy(_:))), + UIMenuItem(title: "高亮", action: #selector(rd_highlight(_:))), + UIMenuItem(title: "批注", action: #selector(rd_annotate(_:))) + ] + menuController.setTargetRect(targetRect, in: coreTextRenderView ?? self) + menuController.setMenuVisible(true, animated: true) + } + + private func hideSelectionMenu() { + UIMenuController.shared.setMenuVisible(false, animated: true) + } + + private var coreTextRenderView: RDEPUBTextPageRenderView? { +#if canImport(DTCoreText) + return coreTextContentView +#else + return nil +#endif + } + + private func highlight(at point: CGPoint) -> RDEPUBHighlight? { + guard let page = currentPage else { return nil } + let absoluteRange = backgroundOverlayView.absoluteRange(at: point) ?? overlayView.absoluteRange(at: point) + guard let absoluteRange else { return nil } + let matches = currentHighlights.filter { highlight in + guard highlight.location.href == page.href, + let range = RDEPUBTextOffsetRangeInfo.decode(from: highlight.rangeInfo)?.nsRange else { + return false + } + return NSIntersectionRange(range, absoluteRange).length > 0 + } + return matches.sorted { lhs, rhs in + let lhsRange = RDEPUBTextOffsetRangeInfo.decode(from: lhs.rangeInfo)?.nsRange?.length ?? .max + let rhsRange = RDEPUBTextOffsetRangeInfo.decode(from: rhs.rangeInfo)?.nsRange?.length ?? .max + if lhs.hasNote != rhs.hasNote { + return lhs.hasNote && !rhs.hasNote + } + return lhsRange < rhsRange + }.first + } + + private func highlightSourceRect(for highlight: RDEPUBHighlight, fallbackPoint: CGPoint) -> CGRect? { + guard let range = RDEPUBTextOffsetRangeInfo.decode(from: highlight.rangeInfo)?.nsRange else { + let fallbackRect = CGRect(origin: fallbackPoint, size: CGSize(width: 1, height: 1)) + return overlayView.convert(fallbackRect, to: self) + } + let rects = interactionController.selectionRects(for: range) + if let first = rects.first { + var unionRect = first + for rect in rects.dropFirst() { + unionRect = unionRect.union(rect) + } + return overlayView.convert(unionRect, to: self) + } + let fallbackRect = CGRect(origin: fallbackPoint, size: CGSize(width: 1, height: 1)) + return overlayView.convert(fallbackRect, to: self) + } + + override func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool { + if gestureRecognizer === panGestureRecognizer { + return selectionController.isSelecting + } + if gestureRecognizer === tapGestureRecognizer { + guard let tapGestureRecognizer = gestureRecognizer as? UITapGestureRecognizer else { + return false + } + if selectionController.hasActiveSelection { + return true + } + let point = tapGestureRecognizer.location(in: overlayView) + return highlight(at: point) != nil + } + return true + } + + func gestureRecognizer( + _ gestureRecognizer: UIGestureRecognizer, + shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer + ) -> Bool { + gestureRecognizer === longPressGestureRecognizer || gestureRecognizer === panGestureRecognizer + } } // MARK: - UIColor Extension diff --git a/Sources/RDReaderView/EPUBUI/TextPage/RDEPUBTextSelectionController.swift b/Sources/RDReaderView/EPUBUI/TextPage/RDEPUBTextSelectionController.swift index 3089a61..6daeac6 100644 --- a/Sources/RDReaderView/EPUBUI/TextPage/RDEPUBTextSelectionController.swift +++ b/Sources/RDReaderView/EPUBUI/TextPage/RDEPUBTextSelectionController.swift @@ -1,49 +1,146 @@ import UIKit -/// 负责管理文本选区、UITextView 代理和菜单定位。 -/// 对齐 WXRead 的选择模型:UITextView 处理原生选择,高亮通过 attributed string 属性绘制。 -final class RDEPUBTextSelectionController: NSObject, UITextViewDelegate { +/// 负责管理文本选区和 CoreText 命中测试。 +/// 对齐 WXRead 的选择模型:触摸命中和最终高亮共用同一套字符范围。 +final class RDEPUBTextSelectionController: NSObject { - private var isSelectionFromInteraction = false - private var selectionMenuAnchorRect: CGRect? + private(set) var isSelecting = false + private var selectionStartIndex: Int = NSNotFound + private var selectionEndIndex: Int = NSNotFound /// 选区变化回调,通知视图层更新 UI var onSelectionChanged: ((RDEPUBSelection?) -> Void)? /// 获取当前页面数据 var pageProvider: (() -> RDEPUBTextPage?)? - // MARK: - UITextViewDelegate - - func textViewDidChangeSelection(_ textView: UITextView) { - textViewDidChangeSelection(textView, page: pageProvider?()) + var hasActiveSelection: Bool { + selectedAbsoluteRange != nil } - func textViewDidChangeSelection(_ textView: UITextView, page: RDEPUBTextPage?) { - guard !isSelectionFromInteraction else { return } - guard let page else { - onSelectionChanged?(nil) + var selectedAbsoluteRange: NSRange? { + guard selectionStartIndex != NSNotFound, + selectionEndIndex != NSNotFound else { + return nil + } + let lower = min(selectionStartIndex, selectionEndIndex) + let upper = max(selectionStartIndex, selectionEndIndex) + return NSRange(location: lower, length: max(upper - lower + 1, 1)) + } + + func handleLongPress( + _ gesture: UILongPressGestureRecognizer, + renderView: RDEPUBTextPageRenderView?, + interactionController: RDEPUBPageInteractionController + ) { + guard let renderView else { return } + let point = gesture.location(in: renderView) + + switch gesture.state { + case .began: + beginSelection(at: point, renderView: renderView, interactionController: interactionController) + case .changed: + updateSelection(at: point, renderView: renderView, interactionController: interactionController) + case .ended: + isSelecting = false + case .cancelled, .failed: + clearSelection(renderView: renderView) + default: + break + } + } + + func handlePan( + _ gesture: UIPanGestureRecognizer, + renderView: RDEPUBTextPageRenderView?, + interactionController: RDEPUBPageInteractionController + ) { + guard isSelecting, let renderView else { return } + let point = gesture.location(in: renderView) + + switch gesture.state { + case .began, .changed: + updateSelection(at: point, renderView: renderView, interactionController: interactionController) + case .ended: + isSelecting = false + case .cancelled, .failed: + clearSelection(renderView: renderView) + default: + break + } + } + + func menuAnchorRect(interactionController: RDEPUBPageInteractionController) -> CGRect? { + guard let absoluteRange = selectedAbsoluteRange else { return nil } + return interactionController.menuAnchorRect(for: absoluteRange) + } + + func clearSelection(renderView: RDEPUBTextPageRenderView? = nil) { + isSelecting = false + selectionStartIndex = NSNotFound + selectionEndIndex = NSNotFound + renderView?.selectionRects = [] + UIMenuController.shared.setMenuVisible(false, animated: true) + onSelectionChanged?(nil) + } + + private func beginSelection( + at point: CGPoint, + renderView: RDEPUBTextPageRenderView, + interactionController: RDEPUBPageInteractionController + ) { + guard let index = interactionController.characterIndexForViewPoint(at: point, in: renderView) else { + clearSelection(renderView: renderView) + return + } + selectionStartIndex = index + selectionEndIndex = index + isSelecting = true + applySelection(renderView: renderView, interactionController: interactionController) + } + + private func updateSelection( + at point: CGPoint, + renderView: RDEPUBTextPageRenderView, + interactionController: RDEPUBPageInteractionController + ) { + guard selectionStartIndex != NSNotFound, + let index = interactionController.characterIndexForViewPoint(at: point, in: renderView) else { + return + } + selectionEndIndex = index + applySelection(renderView: renderView, interactionController: interactionController) + } + + private func applySelection( + renderView: RDEPUBTextPageRenderView, + interactionController: RDEPUBPageInteractionController + ) { + guard let absoluteRange = selectedAbsoluteRange, + let page = pageProvider?() else { + clearSelection(renderView: renderView) return } - let selectedRange = textView.selectedRange - guard selectedRange.location != NSNotFound, - selectedRange.length > 0, - let attributedText = textView.attributedText else { - onSelectionChanged?(nil) - return + renderView.selectionRects = interactionController.selectionRects(for: absoluteRange) + onSelectionChanged?(makeSelection(from: absoluteRange, page: page)) + } + + private func makeSelection(from absoluteRange: NSRange, page: RDEPUBTextPage) -> RDEPUBSelection? { + guard absoluteRange.location != NSNotFound, + absoluteRange.length > 0, + NSMaxRange(absoluteRange) <= page.chapterContent.length else { + return nil } - let source = attributedText.string as NSString - let selectedText = source.substring(with: selectedRange).trimmingCharacters(in: .whitespacesAndNewlines) - guard !selectedText.isEmpty else { - onSelectionChanged?(nil) - return + let selectedText = page.chapterContent.attributedSubstring(from: absoluteRange).string + guard !selectedText.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty else { + return nil } - let globalStart = page.pageStartOffset + selectedRange.location - let globalEnd = globalStart + selectedRange.length let totalLength = max(page.chapterContent.length - 1, 1) - let selection = RDEPUBSelection( + let globalStart = absoluteRange.location + let globalEnd = absoluteRange.location + absoluteRange.length + return RDEPUBSelection( location: RDEPUBLocation( href: page.href, progression: Double(globalStart) / Double(totalLength), @@ -53,45 +150,5 @@ final class RDEPUBTextSelectionController: NSObject, UITextViewDelegate { text: selectedText, rangeInfo: RDEPUBTextOffsetRangeInfo(href: page.href, start: globalStart, end: globalEnd).jsonString() ) - onSelectionChanged?(selection) - } - - // MARK: - 选区清除 - - func clearSelection() { - isSelectionFromInteraction = false - selectionMenuAnchorRect = nil - UIMenuController.shared.setMenuVisible(false, animated: true) - onSelectionChanged?(nil) - } - - func clearSelection(textView: UITextView) { - textView.selectedRange = NSRange(location: 0, length: 0) - clearSelection() - } - - // MARK: - 菜单显示 - - func showSelectionMenuIfNeeded( - in hostView: UIView, - textView: UITextView, - interactionController: RDEPUBPageInteractionController - ) { - guard textView.selectedRange.length > 0, - let textRange = textView.selectedTextRange else { return } - - let rect = textView.firstRect(for: textRange) - guard !rect.isNull, !rect.isEmpty else { return } - - let menuRect = hostView.convert(rect, from: textView) - hostView.becomeFirstResponder() - let menuController = UIMenuController.shared - menuController.menuItems = [ - UIMenuItem(title: "拷贝", action: #selector(RDEPUBTextContentView.rd_copy(_:))), - UIMenuItem(title: "高亮", action: #selector(RDEPUBTextContentView.rd_highlight(_:))), - UIMenuItem(title: "批注", action: #selector(RDEPUBTextContentView.rd_annotate(_:))) - ] - menuController.setTargetRect(menuRect, in: hostView) - menuController.setMenuVisible(true, animated: true) } }