Introducing `-[RCTView reactAccessibleView]`

Summary:
Sometimes, when we implement some custom RN view, we have to proxy all accessible atributes directly to some subview which actually has accesible content. So, in other words, this allows bypass some axillary views in terms of accessibility.
Concreate example which this approach supposed to fix:
https://github.com/facebook/react-native/pull/14200/files#diff-e5f6b1386b7ba07fd887bca11ec828a4R208

Reviewed By: mmmulani

Differential Revision: D5143860

fbshipit-source-id: 6d7ce747f28e5a31d32c925b8ad8fd4b98ce1de1
This commit is contained in:
Valentin Shergin 2017-06-02 14:17:56 -07:00 committed by Facebook Github Bot
parent 20217873d4
commit 072d2709df
7 changed files with 55 additions and 7 deletions

View File

@ -357,6 +357,13 @@ RCT_NOT_IMPLEMENTED(- (instancetype)initWithCoder:(NSCoder *)aDecoder)
eventCount:_nativeEventCount];
}
#pragma mark - Accessibility
- (UIView *)reactAccessibilityElement
{
return _textField;
}
#pragma mark - Focus control deledation
- (void)reactFocus

View File

@ -530,6 +530,13 @@ static BOOL findMismatch(NSString *first, NSString *second, NSRange *firstRange,
eventCount:_nativeEventCount];
}
#pragma mark - Accessibility
- (UIView *)reactAccessibilityElement
{
return _textView;
}
#pragma mark - Focus control deledation
- (void)reactFocus

View File

@ -779,6 +779,7 @@ exports.examples = [
padding: 10,
paddingTop: 20,
}}
testID="singleline_textinput"
placeholder="Placeholder defines intrinsic size"
/>
</View>
@ -798,6 +799,7 @@ exports.examples = [
paddingTop: 20,
maxHeight: 100
}}
testID="multiline_textinput"
multiline={true}
placeholder="Placeholder defines intrinsic size"
/>

View File

@ -211,6 +211,20 @@ RCT_NOT_IMPLEMENTED(- (instancetype)initWithCoder:unused)
return CGRectContainsPoint(hitFrame, point);
}
- (UIView *)reactAccessibilityElement
{
return self;
}
- (BOOL)isAccessibilityElement
{
if (self.reactAccessibilityElement == self) {
return [super isAccessibilityElement];
}
return NO;
}
- (BOOL)accessibilityActivate
{
if (_onAccessibilityTap) {

View File

@ -114,12 +114,16 @@ RCT_EXPORT_VIEW_PROPERTY(hasTVPreferredFocus, BOOL)
RCT_EXPORT_VIEW_PROPERTY(tvParallaxProperties, NSDictionary)
#endif
RCT_REMAP_VIEW_PROPERTY(accessible, isAccessibilityElement, BOOL)
RCT_EXPORT_VIEW_PROPERTY(accessibilityLabel, NSString)
RCT_EXPORT_VIEW_PROPERTY(accessibilityTraits, UIAccessibilityTraits)
RCT_EXPORT_VIEW_PROPERTY(accessibilityViewIsModal, BOOL)
// Acessibility related properties
RCT_REMAP_VIEW_PROPERTY(accessible, reactAccessibilityElement.isAccessibilityElement, BOOL)
RCT_REMAP_VIEW_PROPERTY(accessibilityLabel, reactAccessibilityElement.accessibilityLabel, NSString)
RCT_REMAP_VIEW_PROPERTY(accessibilityTraits, reactAccessibilityElement.accessibilityTraits, UIAccessibilityTraits)
RCT_REMAP_VIEW_PROPERTY(accessibilityViewIsModal, reactAccessibilityElement.accessibilityViewIsModal, BOOL)
RCT_REMAP_VIEW_PROPERTY(onAccessibilityTap, reactAccessibilityElement.onAccessibilityTap, RCTDirectEventBlock)
RCT_REMAP_VIEW_PROPERTY(onMagicTap, reactAccessibilityElement.onMagicTap, RCTDirectEventBlock)
RCT_REMAP_VIEW_PROPERTY(testID, reactAccessibilityElement.accessibilityIdentifier, NSString)
RCT_EXPORT_VIEW_PROPERTY(backgroundColor, UIColor)
RCT_REMAP_VIEW_PROPERTY(testID, accessibilityIdentifier, NSString)
RCT_REMAP_VIEW_PROPERTY(backfaceVisibility, layer.doubleSided, css_backface_visibility_t)
RCT_REMAP_VIEW_PROPERTY(opacity, alpha, CGFloat)
RCT_REMAP_VIEW_PROPERTY(shadowColor, layer.shadowColor, CGColor)
@ -220,8 +224,6 @@ RCT_CUSTOM_VIEW_PROPERTY(hitSlop, UIEdgeInsets, RCTView)
}
}
}
RCT_EXPORT_VIEW_PROPERTY(onAccessibilityTap, RCTDirectEventBlock)
RCT_EXPORT_VIEW_PROPERTY(onMagicTap, RCTDirectEventBlock)
#define RCT_VIEW_BORDER_PROPERTY(SIDE) \
RCT_CUSTOM_VIEW_PROPERTY(border##SIDE##Width, float, RCTView) \

View File

@ -86,6 +86,15 @@
@property (nonatomic, readonly) UIEdgeInsets reactCompoundInsets;
@property (nonatomic, readonly) CGRect reactContentFrame;
/**
* The (sub)view which represents this view in terms of accessibility.
* ViewManager will apply all accessibility properties directly to this view.
* May be overriten in view subclass which needs to be accessiblitywise
* transparent in favour of some subview.
* Defaults to `self`.
*/
@property (nonatomic, readonly) UIView *reactAccessibilityElement;
#if RCT_DEV
/**

View File

@ -262,4 +262,11 @@
return UIEdgeInsetsInsetRect(self.bounds, self.reactCompoundInsets);
}
#pragma mark - Accessiblity
- (UIView *)reactAccessibilityElement
{
return self;
}
@end