Skip to content
Permalink
Browse files

Move accessibility props to UIView+React (#24743)

Summary:
React Native Gesture Handler uses a `RCTViewManager` subclass to manage `UIControl` so the cast to set accessibility props is not safe. This moves the accessibility props we set to `UIView+React` so they can be used safely on any `UIView`.

![image](https://user-images.githubusercontent.com/2677334/57042641-46e42700-6c33-11e9-9a97-76661ad5d14d.png)

[General] [Fixed] - Move accessibility props to UIView+React
Pull Request resolved: #24743

Differential Revision: D15258062

Pulled By: cpojer

fbshipit-source-id: 4a25b79407e5cb7b3b368c7506161e989794bb26
  • Loading branch information...
janicduplessis authored and facebook-github-bot committed May 8, 2019
1 parent b4b9c0f commit 9261035c2bf2fe9522806fb1c535a1835e7acfa2
Showing with 45 additions and 15 deletions.
  1. +0 −7 React/Views/RCTView.h
  2. +5 −5 React/Views/RCTView.m
  3. +3 −3 React/Views/RCTViewManager.m
  4. +7 −0 React/Views/UIView+React.h
  5. +30 −0 React/Views/UIView+React.m
@@ -28,13 +28,6 @@ extern const UIAccessibilityTraits SwitchAccessibilityTrait;
@property (nonatomic, copy) RCTDirectEventBlock onMagicTap;
@property (nonatomic, copy) RCTDirectEventBlock onAccessibilityEscape;

/**
* Accessibility properties
*/
@property (nonatomic, copy) NSArray <NSString *> *accessibilityActions;
@property (nonatomic, copy) NSString *accessibilityRole;
@property (nonatomic, copy) NSArray <NSString *> *accessibilityStates;

/**
* Used to control how touch events are processed.
*/
@@ -158,12 +158,12 @@ - (NSString *)accessibilityLabel

- (NSArray <UIAccessibilityCustomAction *> *)accessibilityCustomActions
{
if (!_accessibilityActions.count) {
if (!self.accessibilityActions.count) {
return nil;
}

NSMutableArray *actions = [NSMutableArray array];
for (NSString *action in _accessibilityActions) {
for (NSString *action in self.accessibilityActions) {
[actions addObject:[[UIAccessibilityCustomAction alloc] initWithName:action
target:self
selector:@selector(didActivateAccessibilityCustomAction:)]];
@@ -189,7 +189,7 @@ - (BOOL)didActivateAccessibilityCustomAction:(UIAccessibilityCustomAction *)acti
- (NSString *)accessibilityValue
{
if ((self.accessibilityTraits & SwitchAccessibilityTrait) == SwitchAccessibilityTrait) {
for (NSString *state in _accessibilityStates) {
for (NSString *state in self.accessibilityStates) {
if ([state isEqualToString:@"checked"]) {
return @"1";
} else if ([state isEqualToString:@"unchecked"]) {
@@ -231,11 +231,11 @@ - (NSString *)accessibilityValue
@"collapsed" : @"collapsed",
};
});
NSString *roleDescription = _accessibilityRole ? roleDescriptions[_accessibilityRole]: nil;
NSString *roleDescription = self.accessibilityRole ? roleDescriptions[self.accessibilityRole]: nil;
if (roleDescription) {
[valueComponents addObject:roleDescription];
}
for (NSString *state in _accessibilityStates) {
for (NSString *state in self.accessibilityStates) {
NSString *stateDescription = state ? stateDescriptions[state] : nil;
if (stateDescription) {
[valueComponents addObject:stateDescription];
@@ -174,7 +174,7 @@ - (RCTShadowView *)shadowView
view.reactAccessibilityElement.accessibilityTraits |= maskedTraits;
} else {
NSString *role = json ? [RCTConvert NSString:json] : @"";
((RCTView *)view.reactAccessibilityElement).accessibilityRole = role;
view.reactAccessibilityElement.accessibilityRole = role;
}
}

@@ -200,9 +200,9 @@ - (RCTShadowView *)shadowView
}
}
if (newStates.count > 0) {
((RCTView *)view.reactAccessibilityElement).accessibilityStates = newStates;
view.reactAccessibilityElement.accessibilityStates = newStates;
} else {
((RCTView *)view.reactAccessibilityElement).accessibilityStates = nil;
view.reactAccessibilityElement.accessibilityStates = nil;
}
}

@@ -113,6 +113,13 @@
*/
@property (nonatomic, readonly) UIView *reactAccessibilityElement;

/**
* Accessibility properties
*/
@property (nonatomic, copy) NSArray <NSString *> *accessibilityActions;
@property (nonatomic, copy) NSString *accessibilityRole;
@property (nonatomic, copy) NSArray <NSString *> *accessibilityStates;

/**
* Used in debugging to get a description of the view hierarchy rooted at
* the current view.
@@ -297,6 +297,36 @@ - (UIView *)reactAccessibilityElement
return self;
}

- (NSArray<NSString *> *)accessibilityActions
{
return objc_getAssociatedObject(self, _cmd);
}

- (void)setAccessibilityActions:(NSArray<NSString *> *)accessibilityActions
{
objc_setAssociatedObject(self, @selector(accessibilityActions), accessibilityActions, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

- (NSString *)accessibilityRole
{
return objc_getAssociatedObject(self, _cmd);
}

- (void)setAccessibilityRole:(NSString *)accessibilityRole
{
objc_setAssociatedObject(self, @selector(accessibilityRole), accessibilityRole, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

- (NSArray<NSString *> *)accessibilityStates
{
return objc_getAssociatedObject(self, _cmd);
}

- (void)setAccessibilityStates:(NSArray<NSString *> *)accessibilityStates
{
objc_setAssociatedObject(self, @selector(accessibilityStates), accessibilityStates, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

#pragma mark - Debug

- (void)react_addRecursiveDescriptionToString:(NSMutableString *)string atLevel:(NSUInteger)level

0 comments on commit 9261035

Please sign in to comment.
You can’t perform that action at this time.