Repository navigation
Description
Steps to reproduce
- Create an iOS add-to-app app that keeps a
FlutterEnginealive after dismissing aFlutterViewController. - Run a simple Flutter screen with accessible widgets, for example a
TextField,Text, andElevatedButton. - Present
FlutterViewController(engine: cachedEngine, nibName: nil, bundle: nil). - Enable VoiceOver or inspect the app with Accessibility Inspector. The Flutter text fields/buttons are present in the iOS accessibility tree.
- Dismiss or pop the
FlutterViewControllerwithout destroying theFlutterEngine. - Create and present a new
FlutterViewControllerusing the sameFlutterEngine. - Inspect the Flutter screen again with VoiceOver or Accessibility Inspector.
Expected results
The Flutter semantics tree remains available to iOS accessibility after the engine is reattached to a new FlutterViewController. Text fields, labels, and buttons should still be visible to VoiceOver and Accessibility Inspector.
Actual results
The Flutter UI renders, but the iOS accessibility tree for the Flutter content becomes empty or missing after reusing the same FlutterEngine with a new FlutterViewController.
Destroying and recreating the engine makes accessibility appear again, but that is not viable for add-to-app apps that intentionally share or cache a Flutter engine.
Code sample
Screenshots or Video
Screenshots / Video demonstration
accessibility_repro.mov
Logs
Logs
No Dart exception or crash is required to reproduce. The issue is visible through VoiceOver / Accessibility Inspector: Flutter content renders, but native iOS accessibility elements for the Flutter semantics tree are missing after reattaching the cached engine to a new FlutterViewController.
Flutter Doctor output
Doctor output
[✓] Flutter (Channel stable, 3.41.5, on macOS 15.7.2 24G325 darwin-arm64, locale en-CY)
[308ms]
• Flutter version 3.41.5 on channel stable at /Users/egorbutyrin/fvm/versions/3.41.5
• Upstream repository https://github.com/flutter/flutter.git
• Framework revision 2c9eb20739 (8 weeks ago), 2026-03-17 16:14:01 -0700
• Engine revision 052f31d115
• Dart version 3.11.3
• DevTools version 2.54.2
• Feature flags: enable-web, enable-linux-desktop, enable-macos-desktop,
enable-windows-desktop, enable-android, enable-ios, cli-animations,
enable-native-assets, enable-swift-package-manager, omit-legacy-version-file,
enable-lldb-debugging, enable-uiscene-migration
[✓] Android toolchain - develop for Android devices (Android SDK version 35.0.1)
[1,204ms]
• Android SDK at /Users/egorbutyrin/Library/Android/sdk
• Emulator version 35.5.10.0 (build_id 13402964) (CL:N/A)
• Platform android-36, build-tools 35.0.1
• ANDROID_HOME = /Users/egorbutyrin/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.6+-13368085-b895.109)
• All Android licenses accepted.
[!] Xcode - develop for iOS and macOS (Xcode 26.1.1) [912ms]
• Xcode at /Applications/Xcode-26.1.1.app/Contents/Developer
• Build 17B100
! CocoaPods 1.12.1 out of date (1.16.2 is recommended).
CocoaPods is a package manager for iOS or macOS platform code.
Without CocoaPods, plugins will not work on iOS or macOS.
For more info, see https://flutter.dev/to/platform-plugins
To update CocoaPods, see
https://guides.cocoapods.org/using/getting-started.html#updating-cocoapods
[✓] Chrome - develop for the web [4ms]
• Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome
[✓] Connected device (3 available) [6.0s]
• iPhone 13 mini (26.1) SNAPSHOTTING (mobile) • BD13A4A2-3C5D-4173-916F-D675461D83B4
• ios • com.apple.CoreSimulator.SimRuntime.iOS-26-1 (simulator)
• macOS (desktop) • macos
• darwin-arm64 • macOS 15.7.2 24G325 darwin-arm64
• Chrome (web) • chrome
• web-javascript • Google Chrome 148.0.7778.168
! Error: Browsing on the local area network for iPhone 11 Pro Max (Test). 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 [653ms]
• All expected network resources are available.
! Doctor found issues in 1 category.
Activity
mbcorona commentedon May 18, 2026
Hi @yegor-butyrin-indrive , Thanks for the thorough report and the standalone repro project — much appreciated.
Routing to the accessibility team, with fyi-ios
yegor-butyrin-indrive commentedon May 20, 2026
@mbcorona Noted, thank you. I already have a fix in my local fork, but I have to discuss the CLA with the legal department on my company. I will open a PR by the end of this week/the beginning of the next one, most likely.
chunhtai commentedon May 20, 2026
feels like a bug in ios embedding, reassing to ios team.
severity: This seems like something that would affect a lot of add-to-app users.
flutter-triage-bot commentedon May 20, 2026
The
fyi-ioslabel is redundant with theteam-ioslabel.elitree commentedon Jun 4, 2026
Hi, just wanted to note that this issue isn't limited to explicit add-to-app / cached-FlutterEngine setups. We're hitting what appears to be the same AccessibilityBridge teardown in a standard production Flutter app. There's no deliberate engine caching or multi-FlutterViewController flow on our side.
In our case the trigger is an ordinary UI interaction: selecting an item from a Material DropdownMenu. Immediately after the selection, the entire iOS accessibility tree for the Flutter view collapses and stays gone for the rest of the session. A debug semantics dump shows the Flutter framework semantics tree fully intact throughout. The loss is purely on the iOS/UIKit side, matching the bridge-reset-without-rebuild behavior described in this issue. Only restarting the app (recreating the engine) recovers it.
So in addition to the add-to-app reproduction already linked, there seems to be at least one path to this state in a plain single-engine app, reachable through routine widget interaction. Let me know if it would be helpful to share any further details, thanks.
Environment: Flutter 3.41.9 stable, iOS 26.x.
elitree commentedon Jun 5, 2026
Regarding the DropDownMenu issue I raised in the previous post, I've entered that as a separate bug, #187611, with a similar minimal repro project, only using GoRouter and a DropDownMenu. Even though it has the same broken end state, I can't tell whether it's the same or a different root cause. Thanks for looking into this.
[iOS] Rebind accessibility bridge after view controller changes (flut…
github-actions commentedon Oct 5, 2026
This thread has been automatically locked since there has not been any recent activity after it was closed. If you are still experiencing a similar issue, please open a new bug, including the output of
flutter doctor -vand a minimal reproduction of the issue.