From 863f585be59e1514b901027f903e08d53e45317d Mon Sep 17 00:00:00 2001 From: Adam Comella Date: Mon, 5 Jun 2017 16:08:27 -0700 Subject: [PATCH] iOS: Improve accessibility of multiline TextInputs Summary: Fixes #13691. Prior to this change, VoiceOver generally didn't say anything when selecting a multiline TextInput. The only exception was VoiceOver would announce the TextInput's placeholder if it had one set. After this change, VoiceOver announces the following for multiline TextInputs: - The TextInput's content. - The TextInput's placeholder if the TextInput doesn't have any content in it. - The fact that the TextInput is a textfield. - The cursor position if the TextInput is being edited. This is similar to the behavior of single line TextInputs. This change achieves this by disabling `RCTTextView` as an accessibility element. `RCTTextView` is a subclass of `RCTView` so VoiceOver doesn't recognize this as a textfield. Instead, VoiceOver now sees the child `RCTUITextView` which is a subclass of `UITextView` so VoiceOver does recognize it as a textfield. Additionally, an `accessibilityLabel` implementation was added to `RCTUITextView` in order to take the value of the placeholder into account. Verified the announcements of TextInputs with various props: - No placeholder and no content - Just a placeholder - Just content - Both a placeholder and content Did this for both singe line inputs and multiline inputs. For setting content in multiline inputs, I tested both using the `value` prop and passing children. All other props being equal, these configurations resulted in similar announcements. I verified that the following accessibility props work the same on singleline and multiline TextInputs: - `accessible` - `accessibilityLabel` - `accessibilityTraits` - `accessibilityViewIsModal` - `onAccessibilityTap` - `onMagicTap` Additionally, my team has been using this change in our app. Adam Comella Microsoft Corp. Closes https://github.com/facebook/react-native/pull/14200 Differential Revision: D5185727 Pulled By: shergin fbshipit-source-id: 94271e6c8b089eb82006b52fe7917649d69e74af --- Libraries/Text/RCTUITextView.m | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/Libraries/Text/RCTUITextView.m b/Libraries/Text/RCTUITextView.m index 7b4711a941..b260a73f86 100644 --- a/Libraries/Text/RCTUITextView.m +++ b/Libraries/Text/RCTUITextView.m @@ -52,6 +52,25 @@ static UIColor *defaultPlaceholderTextColor() [[NSNotificationCenter defaultCenter] removeObserver:self]; } +- (NSString *)accessibilityLabel +{ + NSMutableString *accessibilityLabel = [NSMutableString new]; + + NSString *superAccessibilityLabel = [super accessibilityLabel]; + if (superAccessibilityLabel.length > 0) { + [accessibilityLabel appendString:superAccessibilityLabel]; + } + + if (self.placeholderText.length > 0 && self.text.length == 0) { + if (accessibilityLabel.length > 0) { + [accessibilityLabel appendString:@" "]; + } + [accessibilityLabel appendString:self.placeholderText]; + } + + return accessibilityLabel; +} + #pragma mark - Properties - (void)setPlaceholderText:(NSString *)placeholderText