Skip to content

[webview_flutter] Touch Events Pass Through Drawer to Underlying WebView on iOS 26 Beta #174513

@DanielFrTB

Description

@DanielFrTB

Steps to reproduce

  1. Run the app on iOS 26 with the attached code
  2. Open the Drawer by swiping from left edge or tapping the menu icon
  3. Tap on any Drawer navigation item

Expected results

Touch events should be handled exclusively by the Drawer
WebView should not receive or respond to touch events when the Drawer is open
Only the Drawer navigation should be triggered

Actual results

Touch events on Drawer items also trigger interactions with the underlying WebView
This causes unintended web page interactions (clicks, scrolling, etc.)

Code sample

import 'package:flutter/material.dart';
import 'package:webview_flutter/webview_flutter.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo with WebView',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
        useMaterial3: true,
      ),
      home: const MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});

  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  int _selectedIndex = 0;
  late WebViewController webViewController;

  static const TextStyle optionStyle = TextStyle(
    fontSize: 30,
    fontWeight: FontWeight.bold,
  );

  @override
  void initState() {
    super.initState();
    // Initialize WebViewController
    webViewController = WebViewController()
      ..setJavaScriptMode(JavaScriptMode.unrestricted)
      ..setNavigationDelegate(
        NavigationDelegate(
          onProgress: (int progress) {
            // Update loading bar if needed
            debugPrint('Loading progress: $progress%');
          },
          onPageStarted: (String url) {
            debugPrint('Page started loading: $url');
          },
          onPageFinished: (String url) {
            debugPrint('Page finished loading: $url');
          },
          onHttpError: (HttpResponseError error) {
            debugPrint('HTTP error: $error');
          },
          onWebResourceError: (WebResourceError error) {
            debugPrint('Web resource error: $error');
          },
          onNavigationRequest: (NavigationRequest request) {
            // Allow all navigation requests
            return NavigationDecision.navigate;
          },
        ),
      )
      ..loadRequest(Uri.parse('https://flutter.dev'));
  }

  List<Widget> get _widgetOptions => <Widget>[
    const Center(
      child: Text(
        'Home Screen',
        style: optionStyle,
      ),
    ),
    const Center(
      child: Text(
        'Business Screen',
        style: optionStyle,
      ),
    ),
    const Center(
      child: Text(
        'School Screen',
        style: optionStyle,
      ),
    ),
    // WebView screen
    WebViewWidget(controller: webViewController),
  ];

  void _onItemTapped(int index) {
    setState(() {
      _selectedIndex = index;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
        title: Text(widget.title),
        leading: Builder(
          builder: (context) {
            return IconButton(
              icon: const Icon(Icons.menu),
              onPressed: () {
                Scaffold.of(context).openDrawer();
              },
            );
          },
        ),
      ),
      body: _widgetOptions[_selectedIndex],
      drawer: Drawer(
        // Add a ListView to the drawer. This ensures the user can scroll
        // through the options in the drawer if there isn't enough vertical
        // space to fit everything.
        child: ListView(
          // Important: Remove any padding from the ListView.
          padding: EdgeInsets.zero,
          children: [
            const DrawerHeader(
              decoration: BoxDecoration(color: Colors.blue),
              child: Text(
                'Navigation Menu',
                style: TextStyle(
                  color: Colors.white,
                  fontSize: 24,
                ),
              ),
            ),
            ListTile(
              leading: const Icon(Icons.home),
              title: const Text('Home'),
              selected: _selectedIndex == 0,
              onTap: () {
                // Update the state of the app
                _onItemTapped(0);
                // Then close the drawer
                Navigator.pop(context);
              },
            ),
            ListTile(
              leading: const Icon(Icons.business),
              title: const Text('Business'),
              selected: _selectedIndex == 1,
              onTap: () {
                // Update the state of the app
                _onItemTapped(1);
                // Then close the drawer
                Navigator.pop(context);
              },
            ),
            ListTile(
              leading: const Icon(Icons.school),
              title: const Text('School'),
              selected: _selectedIndex == 2,
              onTap: () {
                // Update the state of the app
                _onItemTapped(2);
                // Then close the drawer
                Navigator.pop(context);
              },
            ),
            ListTile(
              leading: const Icon(Icons.web),
              title: const Text('Flutter.dev WebView'),
              selected: _selectedIndex == 3,
              onTap: () {
                // Update the state of the app
                _onItemTapped(3);
                // Then close the drawer
                Navigator.pop(context);
              },
            ),
          ],
        ),
      ),
    );
  }
}

Screenshots or Video

Video demonstration (my finger touch only at the Drawer)
iOS_26_touch_issue.mov

Flutter Doctor output

Doctor output
[✓] Flutter (Channel stable, 3.29.3, on macOS 15.6 24G84 darwin-arm64, locale en-IL) [1,525ms]
    • Flutter version 3.29.3 on channel stable at /Users/daniel.f/git/flutter
    • Upstream repository https://github.com/flutter/flutter.git
    • Framework revision ea121f8859 (5 months ago), 2025-04-11 19:10:07 +0000
    • Engine revision cf56914b32
    • Dart version 3.7.2
    • DevTools version 2.42.3

[✓] Android toolchain - develop for Android devices (Android SDK version 35.0.0) [1,663ms]
    • Android SDK at /Users/daniel.f/Library/Android/sdk
    • Platform android-35, build-tools 35.0.0
    • ANDROID_HOME = /Users/daniel.f/Library/Android/sdk
    • Java binary at: /Applications/Android Studio.app/Contents/jbr/Contents/Home/bin/java
      This is the JDK bundled with the latest Android Studio installation on this machine.
      To manually set the JDK path, use: `flutter config --jdk-dir="path/to/jdk"`.
    • Java version OpenJDK Runtime Environment (build 21.0.5+-12932927-b750.29)
    • All Android licenses accepted.

[✓] Xcode - develop for iOS and macOS (Xcode 16.1) [1,146ms]
    • Xcode at /Applications/Xcode.app/Contents/Developer
    • Build 16B40
    • CocoaPods version 1.16.2

[✓] Chrome - develop for the web [108ms]
    • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome

[✓] Android Studio (version 2024.3) [107ms]
    • Android Studio at /Applications/Android Studio.app/Contents
    • Flutter plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/9212-flutter
    • Dart plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/6351-dart
    • Java version OpenJDK Runtime Environment (build 21.0.5+-12932927-b750.29)

[✓] IntelliJ IDEA Ultimate Edition (version 2023.1.7) [106ms]
    • IntelliJ at /Users/daniel.f/Applications/IntelliJ IDEA Ultimate.app
    • Flutter plugin version 78.2.1
    • Dart plugin version 231.9414.10

[✓] VS Code (version 1.103.1) [14ms]
    • VS Code at /Applications/Visual Studio Code.app/Contents
    • Flutter extension version 3.116.0

[✓] Connected device (5 available) [6.8s]
    • Daniel (wireless) (mobile)           •  ios            • iOS 17.6.1 21G93
    • Phone (wireless) (mobile) •  ios            • iOS 26.0 23A5330a
    • macOS (desktop)                      • macos                     • darwin-arm64   • macOS 15.6 24G84 darwin-arm64
    • Mac Designed for iPad (desktop)      • mac-designed-for-ipad     • darwin         • macOS 15.6 24G84 darwin-arm64
    • Chrome (web)                         • chrome                    • web-javascript • Google Chrome 139.0.7258.139
    ! Error: Browsing on the local area network for iPhone. Ensure the device is unlocked and attached with a cable or associated with the same local area network as this Mac.
      The device must be opted into Developer Mode to connect wirelessly. (code -27)
    ! Error: Browsing on the local area network for iPhone. Ensure the device is unlocked and attached with a cable or associated with the same local area network as this Mac.
      The device must be opted into Developer Mode to connect wirelessly. (code -27)
    ! Error: Browsing on the local area network for iPhone (5). Ensure the device is unlocked and attached with a cable or associated with the same local area network as this Mac.
      The device must be opted into Developer Mode to connect wirelessly. (code -27)

[✓] Network resources [477ms]
    • All expected network resources are available.

• No issues found!

Metadata

Metadata

Assignees

Labels

P1High-priority issues at the top of the work liste: OS-version specificAffects only some versions of the relevant operating systemengineflutter/engine related. See also e: labels.f: material designflutter/packages/flutter/material repository.found in release: 3.35Found to occur in 3.35found in release: 3.36Found to occur in 3.36frameworkflutter/packages/flutter repository. See also f: labels.has reproducible stepsThe issue has been confirmed reproducible and is ready to work onp: webviewThe WebView pluginpackageflutter/packages repository. See also p: labels.platform-iosiOS applications specificallyr: fixedIssue is closed as already fixed in a newer versionteam-iosOwned by iOS platform teamtriaged-iosTriaged by iOS platform team

Type

No type

Projects

Status

Done

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions