You need to enable JavaScript to run this app. 如何在WKWebView上层叠加PKCanvasView 兼容Pencil绘图与网页滚动
优惠活动
大模型
产品
解决方案
定价
更多

如何在WKWebView上层叠加PKCanvasView 兼容Pencil绘图与网页滚动

优化集成方案

原hacky方案的核心问题

你之前搭的可运行版本灵活度差,根源是破坏了两个系统组件的原生事件链路:

  • 把PKCanvasView的绘图手势直接摘下来挂到WKWebView上,相当于切断了PKCanvasView和PencilKit服务的原生响应者绑定,导致toolPicker状态同步、绘制精度管理、自定义手势优先级的能力全部受限
  • 强制让PKCanvasView的hitTest返回nil,没有建立可配置的触控分流逻辑,所有Pencil事件的处理完全依赖硬编码的手势类型过滤,想加自定义规则都找不到合适的切入点

具体实现步骤

基于系统触控事件的分发逻辑,完全不需要手动调用touches系列方法做转发,只要在WKWebView的手势代理层做精准的类型分流,就能同时满足两个核心需求:保持WKWebView对所有手指触控的原生处理能力,不改变滚动、点击、缩放的原生表现;完整保留PKCanvasView和PencilKit的全量能力,toolPicker、压感识别、撤销重做等特性都不受影响。

  • 自定义WKWebView子类,实现触控类型分流逻辑,不需要重写webView内部的事件处理流程
    class FilteredWebView: WKWebView, UIGestureRecognizerDelegate {
        // 绑定上层canvas的绘图手势,用于接收Pencil类型的事件
        weak var targetDrawingGesture: UIGestureRecognizer?
    
        override init(frame: CGRect, configuration: WKWebViewConfiguration) {
            super.init(frame: frame, configuration: configuration)
            // 给webView的所有内置手势设置代理,在事件分发前做类型判断
            gestureRecognizers?.forEach { $0.delegate = self }
        }
    
        func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool {
            // 判断为Apple Pencil触控时:不交给webView处理,直接转发给canvas的绘图手势
            if touch.type == .pencil {
                targetDrawingGesture?.receiveTouch(touch)
                return false
            }
            // 手指触控完全放行,走webView原生处理逻辑
            return true
        }
    }
    
  • 调整视图层级的交互配置,不再重写PKCanvasView的hitTest方法:
    • 保持webView在下层、透明PKCanvasView在上层的层级关系
    • 把PKCanvasView的isUserInteractionEnabled设置为false,让所有触控事件默认穿透到下层的webView,不需要靠返回nil的hitTest做穿透
    • 保留PKCanvasView对自身drawingGestureRecognizer的持有关系,把这个手势赋值给webView的targetDrawingGesture属性
    • 删掉之前把canvas的drawingGestureRecognizer手动添加到webView上的代码,避免手势重复接收事件
  • 保持原有PencilKit的绑定逻辑不变:
    • 继续用toolPicker.addObserver(canvas)绑定toolPicker和canvas,不需要调整第一响应者的设置
    • 不需要额外修改canvas绘图手势的allowedTouchTypes属性,所有Pencil事件的接收都由webView的分流逻辑精准控制

方案的实际优势

  • 无侵入打断WKWebView的原生触控链路:手指触发的滚动、点击、表单交互、缩放手势完全走系统原生流程,不存在滚动偏移、手势卡顿的问题
  • 完整保留PencilKit全量能力:绘图手势始终归PKCanvasView所有,toolPicker的状态同步、压感/倾斜度识别、橡皮擦/画笔的效果、图层透明度配置都和独立使用PKCanvasView时完全一致
  • 灵活度可自由扩展:可以随时在分流逻辑里加自定义规则,比如临时禁用绘制、加入双指触控的撤回手势、或者根据网页滚动状态调整绘制的可用范围,不需要改动核心的事件分发逻辑

补充:很多人尝试在hitTest或者touchesBegan阶段判断触控来源,经常会遇到拿不到准确touch类型的问题,其实UIGestureRecognizerDelegate的回调时机刚好是在系统完成触控事件路由前,这里拿到的touch.type是完全准确的,完全不需要手动转发touches方法。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.11.03 22:15:08