Skip to content

fix(iOS): preserve Selected accessibility trait on recycled Fabric views - #57810

Closed
stareezy-1 wants to merge 1 commit into
react:mainfrom
stareezy-1:fix/ios-accessibility-selected-recycled
Closed

fix(iOS): preserve Selected accessibility trait on recycled Fabric views#57810
stareezy-1 wants to merge 1 commit into
react:mainfrom
stareezy-1:fix/ios-accessibility-selected-recycled

Conversation

@stareezy-1

Copy link
Copy Markdown

Summary

Fixes the Selected accessibility trait being lost when a Fabric iOS view is recycled and its role changes while accessibilityState.selected remains true.

Fixes #57515

Changelog:

[IOS] [FIXED] - Accessibility Selected/NotEnabled traits are now preserved when a recycled Fabric view's role changes

Problem

In RCTViewComponentView updateProps, two writers update self.accessibilityTraits:

  1. accessibilityTraits (role change): replaces the full bitmask — does NOT include Selected/NotEnabled
  2. accessibilityState (state change): ORs in Selected/NotEnabled

Both diff against retained props. On a recycled view:

  • Lifecycle 1: Button A (role=button, selected=true) → traits = Button | Selected
  • Lifecycle 2: Plain view (role=none, selected=false) → traits = None
  • Lifecycle 3: Button A again (role=button, selected=true) → role changed (none→button) so writer 1 fires: Button. But retained props still show selected=true from lifecycle 1, so writer 2 skips. Selected is lost.

Solution

After the accessibilityTraits writer fires (role change), immediately re-apply Selected/NotEnabled from the current accessibilityState. This is idempotent when the state writer also fires.

Test Plan

  • Recycled view with same accessibilityState.selected=true but different role now retains the Selected trait
  • Accessibility Inspector shows correct traits after toggling between views with different roles
  • No change in behavior for non-recycled views (the state bits are ORed in regardless)

…cycled views

When accessibilityTraits changes (role change), the writer replaces
the full bitmask without Selected/NotEnabled. On a recycled view,
if accessibilityState hasn't changed (stale props match new props),
the state writer skips and the Selected trait is permanently lost.

Re-apply the state bits (Selected/NotEnabled) from the current
accessibilityState immediately after overwriting the role traits.
This is idempotent when the state writer also fires.

Fixes react#57515
@meta-cla meta-cla Bot added the CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. label Aug 4, 2026
@facebook-github-tools facebook-github-tools Bot added the Shared with Meta Applied via automation to indicate that an Issue or Pull Request has been shared with the team. label Aug 4, 2026
@cgoldsby

cgoldsby commented Aug 4, 2026

Copy link
Copy Markdown

Hi @stareezy-1, thanks for your interest in this issue. ❤️

Since this is a duplicate of #57516, let's close this PR. The referenced PR addresses a deep root issue by correcting duplicate writes for accessibilityTraits. In addition, it honors accessibilityTraits as a proper bit mask.

@stareezy-1 stareezy-1 closed this Aug 4, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. Shared with Meta Applied via automation to indicate that an Issue or Pull Request has been shared with the team.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[iOS][Fabric] A recycled Fabric iOS view can lose the Selected accessibility trait after reuse

2 participants