前段时间 GitHub Issue #175099 又提出了一个 iOS 18 的问题,大概就是 webview_flutter 的点击事件出现了'点不动'或'点了不触发'的情况。源头还是 WKWebView(WebKit)内部的手势识别器与 Flutter Engine 里用于'阻止/延迟'手势的 recognizer 之间的冲突。
针对这个问题,去年 iOS 18.2 beta 里出现过类似情况。那时候在 Engine 里,可以通过移除并重新添加 delayingRecognizer 的实现来暂时绕过问题,主要是通过刷新 WebKit 的内部状态从而临时修复。但这个绕过在 iOS 18 上造成了另一个严重回归:overlay 的手势阻止失效、触摸穿透底下的 WebView。因此在最近针对 iOS 18 的条件下,该提交被回退(revert)了。

另外也是因为 Flutter 团队发现这是 Apple / WebKit 的 bug,所以也已经同步上报请求和 Apple 协作。
问题最开始出现在 iOS 18.2 beta 版本上,当页面上先触发了某些 Flutter widget(或者 overlay,比如 context menu / Drawer)后,WKWebView 内的点击(链接、按钮)不再响应(可高亮,但不会激活),需要重新加载 WebView 才恢复。
而具体原因在于,Flutter 在 iOS 的 PlatformView(例如承载 WKWebView 的视图)上实现了一套'手势拦截/延迟'机制:在需要时会把一个 FlutterDelayingGestureRecognizer(delayingRecognizer )切到某些状态(possible, ended, failed 等)来告诉 UIKit 或者其他 recognizers 是否应该阻止/允许手势传递。
而 UIKit 的手势识别器有自己的状态机(possible → recognized/failed / ended ),不同 recognizer 相互之间会有阻塞/依赖关系:

这里需要简单介绍一个背景知识:Flutter + iOS 平台视图的手势处理机制。在 iOS 上当你把一个原生控件(比如 WKWebView)嵌进 Flutter 时,实际上会经历以下层级:
[FlutterView] ← 整个 Flutter 渲染层(Dart UI 层)
├─ Flutter widgets
│ ↑
│ │
│ 手势事件由 Flutter framework(Dart)处理
│ └─ PlatformView (e.g. WKWebView)
│ ↑
│ 手势事件由 UIKit / WebKit 内部 recognizer 处理
Flutter 和 UIKit 都各自有手势识别系统(GestureRecognizer)。为了防止互相抢事件,Flutter engine 在 iOS 上加入了一个'delaying gesture recognizer'(延迟识别器):
它的作用是:当 Flutter 框架检测到某个 widget 想'阻止'事件时(比如
GestureDetector或 overlay 遮罩),Flutter 会让这个delayingRecognizer阻止 UIKit 里的 recognizer(例如 WKWebView 的点击识别器)响应。








