react-native
react-native copied to clipboard
[iOS] VoiceOver reads the placeholder in TextInput
Description
When setting a placeholder
in the TextInput
field, VoiceOver reads the placeholder text. This causes problems when an accessibilityLabel is also provided.
Expected behaviour: Placeholder should not be read by a screen reader as it is just a visual component.
Steps to reproduce
Try this sample code:
import React from 'react';
import {SafeAreaView, StyleSheet, TextInput} from 'react-native';
const TextInputExample = () => {
const [text, onChangeText] = React.useState('');
return (
<SafeAreaView>
<TextInput
placeholder="text input"
accessibilityLabel="text input"
style={styles.input}
onChangeText={onChangeText}
value={text}
/>
</SafeAreaView>
);
};
const styles = StyleSheet.create({
input: {
height: 40,
margin: 12,
borderWidth: 1,
padding: 10,
},
});
export default TextInputExample;
React Native Version
0.74.0
Affected Platforms
Runtime - iOS
Output of npx react-native info
n/a
Stacktrace or Logs
n/a
Reproducer
https://snack.expo.dev/eiduCgHeg-d8A6PLexqp2
Screenshots and Videos
:warning: | Add or Reformat Version Info |
---|---|
:information_source: | We could not find or parse the version number of React Native in your issue report. Please use the template, and report your version including major, minor, and patch numbers - e.g. 0.70.2 |
Can i work on this issue?
Yes, please 🙂
Hi @prateekgarcha , I think I might be able to help with your question.
First, in iOS native development, VoiceOver reads the placeholder value of a UITextField by default. This is the expected behavior.
Secondly, maybe you don't need to add accessibilityLabel="text input"
to your input field. The system will automatically announce this component as a "text field," which is slightly different from your "text input" but serves the same purpose.
Lastly, if you would like to prevent the placeholder value from being read out, I can suggest a workaround. In my approach, I would :
- add a
TouchableOpacity
of the same size as theTextField
over the TextField, - nest a
Text
component within theTouchableOpacity
and set it to display the placeholder value you wish to show, and useaccessibilityElementsHidden={true}
to ensure this value is not readable, - when the user taps the
TouchableOpacity
, enter the editing state and hide theTouchableOpacity
. When the user exits the editing state, if the text field is empty, display theTouchableOpacity
again to simulate a placeholder-like effect.
I'm not sure if this is a good implementation, but I have tested it successfully on an iPhone 12 with iOS 16.1. I hope it helps you.
Here is my code: https://snack.expo.dev/@ziggear/expo-snack-for-prateekgarcha?platform=ios