4

I created an AuthForm component that I use for a sign up and sign in screen after styling the screen I noticed every time I click on the keyboard to type some input everything changes its original placement and some components overlay others and it turns into a mess, how can I fix this?

Here is the code i used

import React, { useState } from "react";
import {
  StyleSheet,
  ImageBackground,
  View,
  TouchableOpacity,
} from "react-native";
import { Text, Button, Input } from "react-native-elements";
import Icon from "react-native-vector-icons/MaterialIcons";
import Spacer from "./Spacer";

const AuthForm = ({
  headerText,
  errorMessage,
  onSubmit,
  submitButtonText,
  subText,
}) => {
  const [email, setEmail] = useState("");
  const [password, setPassword] = useState("");

  return (
    <View style={styles.container}>
      <Spacer>
        <Text style={styles.Text1}>{headerText}</Text>
        <Text style={styles.Text2}>{subText}</Text>
      </Spacer>
      <View style={styles.Input}>
        <Input
          style={styles.Input}
          placeholder="Your email"
          value={email}
          onChangeText={setEmail}
          autoCapitalize="none"
          autoCorrect={false}
          leftIcon={<Icon name="email" size={20} color="#B3C1B3" />}
        />
        <Input
          secureTextEntry
          placeholder="Your password"
          value={password}
          onChangeText={setPassword}
          autoCapitalize="none"
          autoCorrect={false}
          leftIcon={<Icon name="lock" size={20} color="#B3C1B3" />}
        />
      </View>
      {errorMessage ? (
        <Text style={styles.errorMessage}>{errorMessage}</Text>
      ) : null}

      <Spacer>
        <TouchableOpacity
          style={styles.buttonStyle}
          onPress={() => onSubmit({ email, password })}
        >
          <Text style={styles.ButtonText}>{submitButtonText}</Text>
        </TouchableOpacity>
      </Spacer>
    </View>
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
    //justifyContent: "center",
  },
  errorMessage: {
    fontSize: 16,
    color: "red",
    marginLeft: 15,
    marginTop: 15,
    top: "35%",
  },
  buttonStyle: {
    color: "#e8c0c8",
    width: "45%",
    height: "25%",
    backgroundColor: "#fdc2e6",
    justifyContent: "center",
    alignItems: "center",
    borderRadius: 15,
    top: "150%",
    left: "30%",
  },
  ButtonText: {
    color: "#FFFF",
  },
  Text1: {
    top: "420%",
    left: "15%",
    fontSize: 24,
    color: "#ffffff",
  },
  Text2: {
    top: "420%",
    left: "15%",
    fontSize: 14,
    color: "#d9d9d9",
  },
  Input: {
    top: "40%",
    width: "70%",
    left: "15%",
  },
});

export default AuthForm;
Max
  • 412
  • 5
  • 21

2 Answers2

14

Update June 29, 2020. EXPO SDK 38 is out and this setting is available on app.json

{
  "expo": {
    ...your app.json expo config,
    "android": {
      "softwareKeyboardLayoutMode": "pan"
    }
  }
}

Refer to the content in expo blog

New android.softwareKeyboardLayoutMode app.json key One tricky part of building forms in mobile apps is that developers need to ensure that the on-screen “software keyboard” doesn’t obscure the focused form element. Android lets you pick how you want this to be handled: you can resize the entire window so nothing will be drawn under the keyboard, or you can pan the window so the content is not underneath it. The native property that lets you control this is android:windowSoftInputMode .

In the past, all Expo apps have been configured to use the resize mode, but some developers have found this to be problematic for their apps because UI elements such as tab bars will be pushed up above the keyboard when it is enabled. If you would prefer to use the pan mode, you can now set the layout mode directly with android.softwareKeyboardLayoutMode in your app configuration. Find the key in the "android" section of "Configuration with app.json".

Reference about this setting: https://docs.expo.io/workflow/configuration/#android


Answer before Expo 38

I think you may observed this problem on Android but not on iOS?

In that case, you will have to set android:windowSoftInputMode="adjustPan" in your manifest file

E.g.

<application
  android:name=".MainApplication"
  android:allowBackup="true"
  ...
  <activity
    android:name=".MainActivity"
    android:label="@string/app_name"
    ...
    android:windowSoftInputMode="adjustPan">
    ...
  </activity>
  ...
</application>
gie3d
  • 766
  • 4
  • 8
  • am using an android emulator yes but i can't tell if i have the same problem on ios too since am on windows and dont own an iphone – Max May 08 '20 at 13:46
  • if it looks like this https://snack.expo.io/@gie3d/frisky-pudding ?. You may try the solution above. It may solve your problem (android keyboard won't push the whole screen up) or this answer may help you. https://stackoverflow.com/questions/39344140/react-native-how-to-control-what-keyboard-pushes-up – gie3d May 08 '20 at 14:16
  • is there a way to modify my AndroidManifest.xml when using expo ? – Max May 09 '20 at 17:18
  • Sad but true, as far as i know, no... you can modify it after eject from expo. – gie3d May 09 '20 at 17:20
  • This setting is available now in Expo SDK 38. I updated my answer. – gie3d Jun 29 '20 at 08:19
  • Thank you for the update. After 2 hours of researchs, you fixed my issue with 1 line in 1 file. – Mickaël Oct 08 '20 at 21:35
  • Life saver! work in 2022 – yanir midler Apr 25 '22 at 08:53
4

You need to use a component named KeyboardAvoidingView. Here is the link to the official documentation with an example of use : https://facebook.github.io/react-native/docs/keyboardavoidingview

Shirco
  • 45
  • 6
  • the keyboardAvoidingView pushed everything to the top of the screen and squashed it together even giving it a flex of 1 did not seem to solve the problem – Max May 08 '20 at 13:52
  • I think the problem comes from the fact that you are positioning your elements using percentages when you could simply use flex elements and use dp (marginTop: 20) for the margin or padding that you would want. – Shirco May 08 '20 at 16:45
  • i only used percentage so that can achieve a similar look on different screen sizes is i will use px instead hopefully it will solve the problem – Max May 08 '20 at 20:46