[iOS][Fabric] Modal content vanishes from the accessibility tree on repeated present/dismiss cycles (renders on screen, invisible to XCUITest/VoiceOver; dev builds)
Maintainer antworten meist innerhalb von 1 Tag
Dieses Issue hat noch niemand übernommen.
Bewertung
- Schwierigkeit
- 4/5
- Geschätzter Aufwand
- 3-5 Tage
- Anfängerfreundlichkeit
- 52/100
- Issue-Typ
- Bug
- Klarheit
- Größtenteils klar
- Aktivitätsstatus
- Aktiv
- Tech-Stack
- react-native
- Bereich
- accessibility, mobile
Rechercherichtung
Beginne mit dem verlinkten rn-modal-a11y-repro: Führe cycle.yaml in einem Debug iOS-Build aus und vergleiche die erste und zweite Präsentation mit der Maestro-Hierarchie. Verfolge dann den Fabric-Modal-Lebenszyklus rund um RCTFabricModalHostViewController und die gemeldeten Accessibility-Benachrichtigungen; abgeschlossen ist die Arbeit, wenn wiederholte Present/Dismiss-Zyklen das Modal und die Elemente des Basisbildschirms im Accessibility-Baum belassen, einschließlich des bestehenden Accessibility-gesteuerten Ablaufs.
Vom Indexierungsmodell aus dem Issue-Text verfasst.
Beschreibung
Description
On the new architecture (Fabric), after one successful present/dismiss cycle of a <Modal transparent animationType="slide">, the next presentation renders on screen but registers nothing in the accessibility tree — the AX tree contains only status-bar/system elements. Touch still works: tapping the modal's close button by coordinates dismisses it and fully restores the accessibility tree; presenting again after that heal is blind again.
Reproduced in a bare community-CLI template (no Expo, no navigation library, one Modal), on both 0.86.2 and 0.87.0, using an XCUITest-based driver (Maestro) as the accessibility ground truth:
- Fresh launch → presentation 1 fully accessible → presentation 2 blind. Deterministic across app relaunches (Debug builds).
maestro hierarchyin the blind state shows only the status bar (time, battery, cellular) and the app root — no modal subtree, no base-screen elements.- Dismissing by coordinate tap restores everything; the next presentation is blind again.
- Build-mode asymmetry: Debug reproduces on the 2nd presentation every time; Release stayed clean for 40 cycles on the same app/simulator.
The failure state lives in the app process, not the test driver:
- Each open/close cycle above runs in its own
maestro testinvocation (fresh driver process each time) and the poison persists across them. - In the production app where we first hit this (larger surface, several modal hosts), a fresh XCUITest runner still sees the blind tree, and killing/respawning
testmanagerdmid-blindness changes nothing. There the trigger index varied slightly (2nd–3rd presentation, including cross-modal-host sequences: sheet ✓ → menu ✗, and menu ✓ menu ✓ → sheet ✗), so the exact index looks timing-sensitive; the minimal app settles on "2nd presentation". - The unified log shows correctly paired
kAXUserTestingNotificationpayloads (RCTFabricModalHostViewControllerViewDidAppear ↔ ViewDidDisappear) for every presentation including the blind ones — the modal VC lifecycle looks healthy while AX registration is missing. - Waiting 45s in the blind state does not self-heal; only dismissal heals.
AccessibilityInfo.setAccessibilityFocuson the modal content inonShowdoes not prevent it.
Impact: for assistive-technology users on dev builds, a blind modal's close control is not an accessibility element, so there is no announced way out (we could not script VoiceOver on the simulator to confirm end-to-end; the tree evidence above is from XCUITest snapshots, which share the AX infrastructure). For teams running XCUITest/Maestro/Appium suites against dev builds, any test past the second modal presentation fails on missing elements. Since Release builds did not reproduce in our runs, production users are plausibly unaffected — but we have not found what dev-mode dependency gates the bug, so we can't say that with confidence.
Possibly related, but describing different symptoms: #50152 (invisible undismissed modal layer), #48611, #49717.
Steps to reproduce
- Clone https://github.com/hubyrod/rn-modal-a11y-repro (bare
cli inittemplate + oneApp.tsx: a button presenting a transparent slide-animation Modal with a close button; Maestro flows included). npm install && cd ios && pod install && cd ..npx react-native run-ios --mode Debug(iOS simulator).maestro test cycle.yaml— passes (open → close via accessibility taps).maestro test cycle.yamlagain — fails: the modal is visibly presented but "CLOSE" is not in the accessibility tree.maestro hierarchyshows only status-bar elements.maestro test close-by-point.yaml(coordinate tap) — the modal dismisses and the tree is restored.maestro test open-only.yaml— blind again.
React Native Version
0.86.2 (also reproduced identically on a fresh 0.87.0 template)
Affected Platforms
Runtime - iOS, Build - MacOS
Output of npx react-native info
System:
OS: macOS 26.6.2
CPU: (14) arm64 Apple M4 Pro
Memory: 3.53 GB / 48.00 GB
Shell:
version: "5.9"
path: /bin/zsh
Binaries:
Node:
version: 22.14.0
path: /Users/hugo/.nvm/versions/node/v22.14.0/bin/node
Yarn:
version: 1.22.22
path: /opt/homebrew/bin/yarn
npm:
version: 11.3.0
path: /Users/hugo/.nvm/versions/node/v22.14.0/bin/npm
Watchman: Not Found
Managers:
CocoaPods:
version: 1.17.0
path: /opt/homebrew/bin/pod
SDKs:
iOS SDK:
Platforms:
- DriverKit 25.5
- iOS 26.5
- macOS 26.5
- tvOS 26.5
- visionOS 26.5
- watchOS 26.5
Android SDK: Not Found
IDEs:
Android Studio: 2025.2 AI-252.28238.7.2523.14688667
Xcode:
version: 26.6/17F113
path: /usr/bin/xcodebuild
Languages:
Java:
version: 17.0.20
path: /usr/bin/javac
Ruby:
version: 4.0.6
path: /opt/homebrew/bin/ruby
npmPackages:
"@react-native-community/cli":
installed: 20.1.0
wanted: 20.1.0
react:
installed: 19.2.3
wanted: 19.2.3
react-native:
installed: 0.86.2
wanted: 0.86.2
react-native-macos: Not Found
npmGlobalPackages:
"*react-native*": Not Found
Android:
hermesEnabled: true
newArchEnabled: true
iOS:
hermesEnabled: true
newArchEnabled: true
Simulator: iPhone 17, iOS 26.2 runtime. AX probe: Maestro 2.4.0 (XCUITest driver).
Stacktrace or Logs
No crash. Accessibility hierarchy in the blind state (modal visibly presented,
screenshot available) reduces to status-bar/system elements only:
"accessibilityText" : "02:13" — status bar time
"accessibilityText" : "100 % battery power" — status bar
"accessibilityText" : "Cellular" — status bar
"accessibilityText" : "ModalA11yRepro" — app root node (no children with content)
After a coordinate-tap dismissal, the same probe returns the full tree
(OPEN button, counter text). Unified log shows paired
kAXUserTestingNotification payloads from RCTFabricModalHostViewController
(ViewDidAppear/ViewDidDisappear) for blind presentations as well.
Reproducer
https://github.com/hubyrod/rn-modal-a11y-repro
Screenshots and Videos
Screenshot of the blind state (modal fully rendered, presentations: 2) alongside the status-bar-only hierarchy dump is available on request — the reproducer regenerates both in under a minute.
- Vorherrschende Sprache
- C++
- Sterne
- 127k
- Forks
- 25.3k
- PR-Merge-Kennzahlen
- Keine gemergten PRs in 30 T.
Entwicklungsumgebung
- Kein Dockerfile und keine Docker-Compose-Datei
- Hat eine Pull-Request-Vorlage
- Beitragsleitfaden lesen
Erste Schritte
- Lesen Sie das ganze Issue und danach den Beitragsleitfaden des Projekts.
- Schreiben Sie ins Issue, dass Sie es übernehmen — das erspart doppelte Arbeit.
- Forken Sie das Repository und arbeiten Sie in einem Branch.
- Öffnen Sie einen Pull Request, der die Issue-Nummer nennt.
Mehr aus react/react-native
-
Needs: Triage :mag: Platform: Android Platform: iOS
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 75/100
react/react-native#58750 ·
Maintainer antworten meist innerhalb von 1 Tag
-
Needs: Author Feedback Needs: Repro
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 75/100
react/react-native#58659 · 2 Kommentare ·
Maintainer antworten meist innerhalb von 1 Tag
-
Needs: Author Feedback Needs: Repro
Schwierigkeit 1/5 Unter einer Stunde Anfängerfreundlichkeit 92/100
react/react-native#58621 · 1 Kommentar ·
Maintainer antworten meist innerhalb von 1 Tag
-
Needs: Attention Needs: Repro
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 85/100
react/react-native#58610 · 3 Kommentare ·
Maintainer antworten meist innerhalb von 1 Tag
-
Needs: Triage :mag:
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 82/100
react/react-native#58565 · 1 Kommentar · 2 Reaktionen ·
Maintainer antworten meist innerhalb von 1 Tag
Alle Issues in react/react-native
Ähnliche Issues
-
area/ysql kind/bug priority/medium
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 75/100
yugabyte/yugabyte-db#34552 ·
Maintainer antworten meist innerhalb von 1 Tag
-
bug
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 86/100
Maintainer antworten meist innerhalb von 1 Tag
-
bug
Schwierigkeit 1/5 Unter einer Stunde Anfängerfreundlichkeit 94/100
Maintainer antworten meist innerhalb von 1 Tag
-
bug
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 84/100
Maintainer antworten meist innerhalb von 1 Tag
-
ai_p2
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 76/100
ClickHouse/ClickHouse#123351 ·
Maintainer antworten meist innerhalb von 1 Tag