Skip to content

Commit

Permalink
Fix inability to remove 'Disabled' state from AccessibilityStates
Browse files Browse the repository at this point in the history
Summary:
D8842691 split AccessibilityTraits into multiple RN properties.  However, the accessor code did not support REMOVING traits.
This results in buttons that were disabled (AccessibilityTraits & NotEnabled === true) never being enabled.

Fix the issue by making the split accessors properly mask in the bits, allowing you unset them without disturbing bits managed by the other accessor.

NOTE: setting AccessibilityTraits and AccessibilityRole or AccessibilityStates will still result in bugs.

Reviewed By: shergin

Differential Revision: D9661970

fbshipit-source-id: 77d70dd0754f2eaf8cbf895bfc13757c697a76d8
  • Loading branch information
Zack Gomez authored and kelset committed Nov 26, 2018
1 parent 26b5a6e commit 79b3311
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 2 deletions.
2 changes: 2 additions & 0 deletions Libraries/Components/View/ViewAccessibility.js
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ module.exports = {
'radiobutton_checked',
'radiobutton_unchecked',
],
// This must be kept in sync with the AccessibilityRolesMask in RCTViewManager.m
AccessibilityRoles: [
'none',
'button',
Expand All @@ -97,5 +98,6 @@ module.exports = {
'header',
'summary',
],
// This must be kept in sync with the AccessibilityStatesMask in RCTViewManager.m
AccessibilityStates: ['selected', 'disabled'],
};
14 changes: 12 additions & 2 deletions React/Views/RCTViewManager.m
Original file line number Diff line number Diff line change
Expand Up @@ -151,12 +151,22 @@ - (RCTShadowView *)shadowView

RCT_CUSTOM_VIEW_PROPERTY(accessibilityRole, UIAccessibilityTraits, RCTView)
{
view.reactAccessibilityElement.accessibilityTraits |= json ? [RCTConvert UIAccessibilityTraits:json] : defaultView.accessibilityTraits;
// This mask must be kept in sync with the AccessibilityRoles enum defined in ViewAccessibility.js
const UIAccessibilityTraits AccessibilityRolesMask = UIAccessibilityTraitNone | UIAccessibilityTraitButton | UIAccessibilityTraitLink | UIAccessibilityTraitSearchField | UIAccessibilityTraitImage | UIAccessibilityTraitKeyboardKey | UIAccessibilityTraitStaticText | UIAccessibilityTraitAdjustable | UIAccessibilityTraitHeader | UIAccessibilityTraitSummaryElement;

UIAccessibilityTraits newTraits = json ? [RCTConvert UIAccessibilityTraits:json] : defaultView.accessibilityTraits;
UIAccessibilityTraits maskedTraits = newTraits & AccessibilityRolesMask;
view.reactAccessibilityElement.accessibilityTraits = (view.reactAccessibilityElement.accessibilityTraits & ~AccessibilityRolesMask) | maskedTraits;
}

RCT_CUSTOM_VIEW_PROPERTY(accessibilityStates, UIAccessibilityTraits, RCTView)
{
view.reactAccessibilityElement.accessibilityTraits |= json ? [RCTConvert UIAccessibilityTraits:json] : defaultView.accessibilityTraits;
// This mask must be kept in sync with the AccessibilityStates enum defined in ViewAccessibility.js
const UIAccessibilityTraits AccessibilityStatesMask = UIAccessibilityTraitNotEnabled | UIAccessibilityTraitSelected;

UIAccessibilityTraits newTraits = json ? [RCTConvert UIAccessibilityTraits:json] : defaultView.accessibilityTraits;
UIAccessibilityTraits maskedTraits = newTraits & AccessibilityStatesMask;
view.reactAccessibilityElement.accessibilityTraits = (view.reactAccessibilityElement.accessibilityTraits & ~AccessibilityStatesMask) | maskedTraits;
}

RCT_CUSTOM_VIEW_PROPERTY(pointerEvents, RCTPointerEvents, RCTView)
Expand Down

0 comments on commit 79b3311

Please sign in to comment.