0

When I run the app with expo and use my DateFormInput component the Keyboard covers TextInput. I tried to use I , "@pietile-native-kit/keyboard-aware-scrollview", "@types/react-native-keyboard-spacer", "react-native-keyboard-aware-scroll-view" and "react-native-keyboard-spacer", but none of them worked on either IOS or Android.

Here is the component I where I render my TextInput (DateFormInput):

import React from 'react';
import {
  Text,
  StyleSheet,
  View,
  KeyboardAvoidingView,
  ScrollView,
} from 'react-native';

import Box from './Box';
import Button from './Button';
import DateFormInput from './DateFormInput';
import { isValidDate } from '../util';
import strings from '../strings';

interface Props {
  handleSubmit: (formName: string) => void;
  handleOnChange: (formName: string, input: string) => void;
  handleCancelButton: (formName: string) => void;
  toggleInputError: (formName: string, clear?: boolean) => void;
  inputFormText: string;
  inputError: boolean;
  formName: string;
}

export const DDCAndDTNInputForm: React.FC<Props> = (props: Props) => {
  return (
    <Box style={styles.box}>
      <Text>
        {props.formName === 'DrugTest' ? strings.DrugTestDate : strings.DDCDate}
      </Text>
      <View style={{ flex: 1 }}>
        <KeyboardAvoidingView behavior="padding" style={styles.box}>
          <ScrollView style={{ flex: 1 }}>
            <DateFormInput
              type={'datetime'}
              options={{ format: 'MM/DD/YYYY' }}
              placeholder={'MM/DD/YYYY'}
              value={props.inputFormText}
              error={props.inputError}
              onChangeText={text => props.handleOnChange(props.formName, text)}
              onBlur={e => {
                isValidDate(props.inputFormText)
                  ? props.handleSubmit(props.formName)
                  : props.toggleInputError(props.formName, true);
              }}
            />
          </ScrollView>
        </KeyboardAvoidingView>
      </View>

      <Text style={{ color: 'red' }}>
        {props.inputError ? 'Type a valid date' : null}
      </Text>

      <View
        style={{
          flexDirection: 'row',
          justifyContent: 'space-around',
        }}
      >
        <Button
          viewStyle={styles.linkButton}
          title={'CANCEL'}
          onPress={() => {
            props.handleCancelButton(props.formName);
          }}
        />

        <Button
          viewStyle={styles.linkButton}
          title={'SAVE DATE'}
          onPress={() => {
            isValidDate(props.inputFormText)
              ? props.handleSubmit(props.formName)
              : props.toggleInputError(props.formName, true);
          }}
        />
      </View>
    </Box>
  );
};

export default DDCAndDTNInputForm;

const styles = StyleSheet.create({
  linkButton: {
    paddingVertical: 8,
    paddingHorizontal: 16,
    marginVertical: 8,
    flex: 1,
  },
  box: {
    padding: 24,
    marginBottom: 16,
    flex: 1,
  },
});

This is my custom InputText (DateFormInput):

import React from 'react';
import {
  Text,
  StyleProp,
  TextStyle,
  StyleSheet,
  KeyboardType,
  View,
  NativeSyntheticEvent,
  TextInputFocusEventData,
} from 'react-native';
import { TextInputMask } from 'react-native-masked-text';

import { textStyle, colors } from '../styles';

const styles = StyleSheet.create({
  input: {
    marginVertical: 8,
    padding: 16,
    borderWidth: 2,
    borderColor: colors.sectionBackground,
    borderRadius: 8,
    backgroundColor: colors.white,
  },
});

export default (props: {
  label: string;
  value: string;
  labelStyle: StyleProp<TextStyle>;
  keyboardType?: KeyboardType;
  onChangeText: (text: string) => void;
  onBlur?: (e: NativeSyntheticEvent<TextInputFocusEventData>) => void;
  error?: boolean;
  defaultValue?: string;
}) => (
  <View style={{ flexDirection: 'column', alignContent: 'stretch' }}>
    <Text style={[textStyle.formLabel, props.labelStyle]}>{props.label}</Text>
    <TextInputMask
      type={'datetime'}
      options={{ format: 'MM/DD/YYYY' }}
      placeholder={'MM/DD/YYYY'}
      style={[styles.input, props.error ? { borderColor: colors.red } : null]}
      value={props.value}
      onChangeText={props.onChangeText}
      onBlur={props.onBlur}
    />
  </View>
);

2 Answers2

2

For anyone still facing the same problem on sdk 42, I discovered that for some unknown reasons, the keyboard was overlaying my TextInput because they were wrapped in View. So wrapping my TextInput in ScrollView instead, allowed the keyboard to push the inputs upward when rolling out.

Stanley
  • 89
  • 8
0

You have two options to solve your problem.

1) The easy one, into your expo config add property androidStatusBar, like this answer: https://stackoverflow.com/a/44876951/7714108

2) You can use KeyboardAvoidingView but on top of your UI view. Then this component has to be the father, because when I have used as a child, like you are using into you component DDCAndDTNInputForm, it is not working. I am still working on this to try understand why this behaviour. For example in your component try to use like this:

<KeyboardAvoidingView style={{flex: 1} behavior="padding" enabled>
 ... your UI ...
</KeyboardAvoidingView>

This is the reference: https://docs.expo.io/versions/v35.0.0/react-native/keyboardavoidingview/

Xopsy
  • 71
  • 1
  • 6