flutter / flutter/flutter

[iOS] Accessibility tree is lost after reusing a FlutterEngine with a new FlutterViewController

Open
#186,582 6 comments 3 reactions 0 assignees View on GitHub
a: accessibility has reproducible steps P1 platform-ios team-ios triaged-ios
Dominant language
Dart
Stars
179k
Forks
31.1k
PR merge metrics
PR metrics pending

Description

### Steps to reproduce

1. Create an iOS add-to-app app that keeps a `FlutterEngine` alive after dismissing a `FlutterViewController`.
2. Run a simple Flutter screen with accessible widgets, for example a `TextField`, `Text`, and `ElevatedButton`.
3. Present `FlutterViewController(engine: cachedEngine, nibName: nil, bundle: nil)`.
4. Enable VoiceOver or inspect the app with Accessibility Inspector. The Flutter text fields/buttons are present in the iOS accessibility tree.
5. Dismiss or pop the `FlutterViewController` without destroying the `FlutterEngine`.
6. Create and present a new `FlutterViewController` using the same `FlutterEngine`.
7. 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

Code sample

https://github.com/yegor-butyrin-indrive/flutter-ios-accessibility-repro

### Screenshots or Video

Screenshots / Video demonstration

https://github.com/user-attachments/assets/f8688127-45b1-455f-ab91-7414de7834a3

### 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

```console
[✓] 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.
```

Contributor guide

Open the contributing guide

Research direction

Start by running the linked iOS add-to-app reproduction and inspect the FlutterEngine and FlutterViewController reuse lifecycle. Then trace how the iOS accessibility or semantics tree is attached when a cached engine is presented again. Done means VoiceOver and Accessibility Inspector show the Flutter text fields, labels, and buttons after reattachment without recreating the engine.

Written by the indexing model from the issue text.

Assessment

Tech stack
dart, ios
Domain
accessibility, mobile-dev
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.