[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
TouchableOpacityof the same size as theTextFieldover the TextField, - nest a
Textcomponent within theTouchableOpacityand 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 theTouchableOpacityagain 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