fix(iOS): reset accessibilityViewIsModal on view recycle to avoid trapping VoiceOver#57196
fix(iOS): reset accessibilityViewIsModal on view recycle to avoid trapping VoiceOver#57196doracawl wants to merge 1 commit into
Conversation
|
Hi @doracawl! Thank you for your pull request and welcome to our community. Action RequiredIn order to merge any pull request (code, docs, etc.), we require contributors to sign our Contributor License Agreement, and we don't seem to have one on file for you. ProcessIn order for us to review and merge your suggested changes, please sign at https://code.facebook.com/cla. If you are contributing on behalf of someone else (eg your employer), the individual CLA may not be sufficient and your employer may need to sign the corporate CLA. Once the CLA is signed, our tooling will perform checks and validations. Afterwards, the pull request will be tagged with If you have received this in error or have any questions, please contact us at cla@meta.com. Thanks! |
|
Thank you for signing our Contributor License Agreement. We can now accept your code for this (and any) Meta Open Source project. Thanks! |
Summary
RCTViewComponentViewappliesaccessibilityViewIsModalinupdatePropsonly when the prop changes:…but
prepareForRecyclenever resets it. So when a view that hadaria-modal/accessibilityViewIsModalis recycled and later reused for a different view that does not set the prop, the diff isNO (recycled default) == NO (new)andupdatePropsskips it — the staleaccessibilityViewIsModal = YESleaks onto the recycled view.A leftover modal view makes UIKit treat its subtree as the only accessible content, so VoiceOver and UI automation see an empty accessibility tree for the rest of the window until an unrelated layout pass recovers it.
This is easy to hit with transparent modals (e.g. a
react-native-screenstransparentModal) on iOS: open a modal → close it → reopen it. The recycled content view keeps the stale flag and competes with the modal's own transition view, collapsing the whole window's accessibility tree. It is intermittent because it depends on which pooled view instance is reused.Changelog:
[iOS] [Fixed] - Reset
accessibilityViewIsModalinprepareForRecycleso a stale modal flag no longer leaks onto recycled views and traps VoiceOverTest Plan
Repro (iOS, Fabric):
<View aria-modal>(for example the content of a transparent modal), then unmount it so its underlyingRCTViewComponentViewreturns to the recycle pool.aria-modal.accessibilityViewIsModal == YES; VoiceOver /Accessibility Inspector/ amaestro hierarchydump show a collapsed (near-empty) accessibility tree for the window.accessibilityViewIsModal == NO; the accessibility tree is intact.Verified on an iOS 26 simulator with a transparent-modal open → close → reopen cycle: UI-automation flows that read the accessibility tree go from intermittently failing to passing every run.