From e28f33a22234ebd03e4ae83ee20a437cb3aebaab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Burak=20=C4=B0mdat?= Date: Tue, 18 Aug 2026 18:13:36 +0300 Subject: [PATCH] [webview_flutter] Register the iOS platform view with the hit-test gesture policy The default eager policy blocks the platform view's gesture recognizers through Flutter's stateful gesture arena. When that state is stranded the web view stops receiving touches for the rest of its lifetime, which reproduces on iOS 26 where the engine's stuck-state reset is disabled. The doNotBlockGesture policy derives the same blocking decision from hit testing, so there is no recognizer state left to strand. --- .../webview_flutter_wkwebview/CHANGELOG.md | 6 ++++++ ...FWebViewFlutterWKWebViewExternalAPITests.swift | 13 +++++++++++++ .../WebViewFlutterPlugin.swift | 15 ++++++++++++++- .../webview_flutter_wkwebview/pubspec.yaml | 2 +- 4 files changed, 34 insertions(+), 2 deletions(-) diff --git a/packages/webview_flutter/webview_flutter_wkwebview/CHANGELOG.md b/packages/webview_flutter/webview_flutter_wkwebview/CHANGELOG.md index f5a9fd6ef336..39bdc0ad8751 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/CHANGELOG.md +++ b/packages/webview_flutter/webview_flutter_wkwebview/CHANGELOG.md @@ -1,3 +1,9 @@ +## 3.26.1 + +* Fixes web views on iOS becoming unresponsive to touches after the first + interaction by registering the platform view with the hit-test based gesture + blocking policy. + ## 3.26.0 * Adds new method for accessing a native `WKWebView` from a `FlutterPluginRegistrar`. diff --git a/packages/webview_flutter/webview_flutter_wkwebview/darwin/Tests/FWFWebViewFlutterWKWebViewExternalAPITests.swift b/packages/webview_flutter/webview_flutter_wkwebview/darwin/Tests/FWFWebViewFlutterWKWebViewExternalAPITests.swift index cc6e10ba8c70..845685129300 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/darwin/Tests/FWFWebViewFlutterWKWebViewExternalAPITests.swift +++ b/packages/webview_flutter/webview_flutter_wkwebview/darwin/Tests/FWFWebViewFlutterWKWebViewExternalAPITests.swift @@ -84,6 +84,16 @@ import WebKit forIdentifier: 0, withPluginRegistrar: registrar) #expect(result == nil) } + + @MainActor @Test func registersViewFactoryWithHitTestGesturePolicy() throws { + let registrar = TestFlutterPluginRegistrar() + + WebViewFlutterPlugin.register(with: registrar) + + #expect( + registrar.registeredGestureRecognizersBlockingPolicy + == FlutterPlatformViewGestureRecognizersBlockingPolicyDoNotBlockGesture) + } #endif } @@ -128,6 +138,8 @@ class TestFlutterPluginRegistrar: NSObject, FlutterPluginRegistrar { #if os(iOS) var viewController: UIViewController? + var registeredGestureRecognizersBlockingPolicy: + FlutterPlatformViewGestureRecognizersBlockingPolicy? func messenger() -> FlutterBinaryMessenger { return TestBinaryMessenger() @@ -145,6 +157,7 @@ class TestFlutterPluginRegistrar: NSObject, FlutterPluginRegistrar { _ factory: FlutterPlatformViewFactory, withId factoryId: String, gestureRecognizersBlockingPolicy: FlutterPlatformViewGestureRecognizersBlockingPolicy ) { + registeredGestureRecognizersBlockingPolicy = gestureRecognizersBlockingPolicy } func addSceneDelegate(_ delegate: any FlutterSceneLifeCycleDelegate) { diff --git a/packages/webview_flutter/webview_flutter_wkwebview/darwin/webview_flutter_wkwebview/Sources/webview_flutter_wkwebview/WebViewFlutterPlugin.swift b/packages/webview_flutter/webview_flutter_wkwebview/darwin/webview_flutter_wkwebview/Sources/webview_flutter_wkwebview/WebViewFlutterPlugin.swift index 8c9be5e494c8..cb60dc298ab8 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/darwin/webview_flutter_wkwebview/Sources/webview_flutter_wkwebview/WebViewFlutterPlugin.swift +++ b/packages/webview_flutter/webview_flutter_wkwebview/darwin/webview_flutter_wkwebview/Sources/webview_flutter_wkwebview/WebViewFlutterPlugin.swift @@ -34,7 +34,20 @@ public class WebViewFlutterPlugin: NSObject, FlutterPlugin { registrar.addSceneDelegate(plugin) #endif - registrar.register(viewFactory, withId: "plugins.flutter.io/webview") + #if os(iOS) + // The default `eager` policy blocks the platform view's gesture + // recognizers through Flutter's gesture arena, which is stateful. When + // that state is stranded the web view stops receiving touches for the + // rest of its lifetime. `doNotBlockGesture` derives the same decision + // from hit testing instead, so there is no state left to strand. + // See https://github.com/flutter/flutter/issues/175099. + registrar.register( + viewFactory, withId: "plugins.flutter.io/webview", + gestureRecognizersBlockingPolicy: + FlutterPlatformViewGestureRecognizersBlockingPolicyDoNotBlockGesture) + #else + registrar.register(viewFactory, withId: "plugins.flutter.io/webview") + #endif registrar.publish(plugin) } diff --git a/packages/webview_flutter/webview_flutter_wkwebview/pubspec.yaml b/packages/webview_flutter/webview_flutter_wkwebview/pubspec.yaml index 5a1c07a9c271..febae87187bd 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/pubspec.yaml +++ b/packages/webview_flutter/webview_flutter_wkwebview/pubspec.yaml @@ -2,7 +2,7 @@ name: webview_flutter_wkwebview description: A Flutter plugin that provides a WebView widget based on Apple's WKWebView control. repository: https://github.com/flutter/packages/tree/main/packages/webview_flutter/webview_flutter_wkwebview issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+webview%22 -version: 3.26.0 +version: 3.26.1 environment: sdk: ^3.12.0