react-native icon indicating copy to clipboard operation
react-native copied to clipboard

[iOS] VoiceOver reads the placeholder in TextInput

Open prateekgarcha opened this issue 10 months ago • 3 comments

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

IMG_F51B7AE11582-1

prateekgarcha avatar Apr 24 '24 08:04 prateekgarcha

: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

github-actions[bot] avatar Apr 24 '24 08:04 github-actions[bot]

Can i work on this issue?

elencho avatar Apr 25 '24 17:04 elencho

Yes, please 🙂

prateekgarcha avatar Apr 25 '24 19:04 prateekgarcha

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 :

  1. add a TouchableOpacity of the same size as the TextField over the TextField,
  2. nest a Text component within the TouchableOpacity and set it to display the placeholder value you wish to show, and use accessibilityElementsHidden={true} to ensure this value is not readable,
  3. when the user taps the TouchableOpacity, enter the editing state and hide the TouchableOpacity. When the user exits the editing state, if the text field is empty, display the TouchableOpacity 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

ziggear avatar Aug 13 '24 08:08 ziggear