You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

iOS16中PDFKit的PDFPageOverlayViewProvider绑定PKCanvasView触控事件未转发求助

解决PDFView叠加PKCanvasView的Apple Pencil触摸事件问题

核心思路

问题根源是PDFDocumentView的触摸响应优先级高于PKCanvasView,导致Apple Pencil的触摸被拦截。我们需要调整事件响应链,让Pencil触摸优先传递给PKCanvasView,同时保留PDFView的滚动、拖放等常规交互。

具体实现方案

1. 自定义PKCanvasView子类,针对性拦截Pencil触摸

创建PencilPriorityCanvasView,重写触摸相关方法,只对Apple Pencil的触摸事件返回自身,其他事件交给父视图处理:

import UIKit
import PencilKit

class PencilPriorityCanvasView: PKCanvasView {
    override func point(inside point: CGPoint, with event: UIEvent?) -> Bool {
        // 仅响应Apple Pencil的触摸
        guard let touch = event?.touches(for: self)?.first,
              touch.type == .pencil else {
            return false
        }
        return super.point(inside: point, with: event)
    }
    
    override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
        let hitView = super.hitTest(point, with: event)
        // 若为Pencil触摸,确保返回自身
        if let touch = event?.touches(for: self)?.first,
           touch.type == .pencil {
            return hitView == self ? self : nil
        }
        // 其他事件交给父视图,不拦截
        return nil
    }
}

2. 实现PDFPageOverlayViewProvider时使用自定义Canvas

在提供overlay视图时,替换为上面的自定义类,并确保交互开启:

class PDFOverlayProvider: NSObject, PDFPageOverlayViewProvider {
    func pdfView(_ pdfView: PDFView, overlayViewFor page: PDFPage) -> UIView? {
        let canvasView = PencilPriorityCanvasView(frame: .zero)
        canvasView.drawingPolicy = .anyInput
        canvasView.isUserInteractionEnabled = true
        // 用tag绑定PDF页面,方便后续坐标转换
        canvasView.tag = page.hashValue
        return canvasView
    }
    
    func pdfView(_ pdfView: PDFView, willDisplayOverlayView overlayView: UIView, for page: PDFPage) {
        // 让overlay尺寸匹配PDF页面
        overlayView.frame = pdfView.convert(page.bounds(for: .mediaBox), to: pdfView)
    }
}

3. 优化PDFView的手势设置(可选)

如果PDFView的滚动、缩放手势仍有冲突,可调整手势属性避免拦截:

pdfView.isUserInteractionEnabled = true
// 确保滚动、缩放手势不阻断触摸传递
pdfView.scrollView.panGestureRecognizer.cancelsTouchesInView = false
pdfView.scrollView.pinchGestureRecognizer.cancelsTouchesInView = false

关键原理

通过自定义Canvas的hitTest和point(inside:)方法,精准过滤出Apple Pencil的触摸事件并响应,其他触摸(比如手指滚动)会穿透到下层的PDFDocumentView,既保证了绘图功能,又不影响PDFView的常规操作。


内容的提问来源于stack exchange,提问作者larsschwegmann

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 10:41:17