Registration Form different in iOS and Android an i0S React Native

Viewed 93

I've built an app in React Native, but in the registration from I have a problem in iOS. enter image description here

The options are out of the selector, I don't know which is the problem. This is my code:

import i18n from "i18n-js";
import {FontAwesome5} from "@expo/vector-icons";
import React, {useReducer, useEffect, useRef} from "react";
import {
  View,
  Text,
  ActivityIndicator,
  TouchableHighlight,
  StyleSheet,
  ScrollView,
} from "react-native";

import {Form, FormComponent} from "../components/form";
import type {FormData} from "../components/form/types";
import UserModel from "../models/UserModel";

const reducer = (state, action) => {
  switch (action.type) {
    case "LOADING":
      return {...state, loading: true, ready: false};
    case "FAILED":
      return {...state, failed: true, loading: false};
    case "SUCCESS":
      return {...state, failed: false, success: true, loading: false};
    case "READY":
      return {...state, success: false, failed: false, ready: true};
  }
};

const initState = {
  loading: false,
  failed: false,
  success: false,
  ready: true,
};

export default function RegisterScreen(props) {
  const {navigation} = props;
  const [state, dispatch] = useReducer(reducer, initState);
  const formRef = useRef(
    new Form([
      {
        name: "name",
        label: i18n.t("Username"),
        required: true,
        group: 1,
        type: "txt",
        validatation: (value, setError) => {
          // eslint-disable-next-line no-useless-escape
          if (!value.match(/^(?=.{3,20}$)[a-zA-Z0-9_\-]+$/gm)) {
            setError(
              `${i18n.t(
                "Username needs to be between 3 to 20 characters long",
              )}.${i18n.t(
                " and can only contains: alphabits, digits, _ and -",
              )}`,
            );
            return false;
          }
          return true;
        },
      },
      {
        name: "mail",
        label: i18n.t("Email"),
        required: true,
        group: 1,
        type: "txt",
        validatation: (value, errorMessage) => {
          if (
            // eslint-disable-next-line no-useless-escape
            value.match(/^[a-zA-Z0-9._\-]+@[a-zA-Z0-9_\-]+\.[a-zA-Z0-9.]+$/)
          ) {
            return true;
          }
          errorMessage(i18n.t("Invalid Email Address"));
          return false;
        },
      },
      {
        name: "pass",
        label: i18n.t("Password"),
        required: true,
        group: 1,
        type: "txt",
        isSecurityText: true,
        validatation: (value, errorMessage) => {
          if (!value.match(/^.{6,}$/)) {
            errorMessage(i18n.t("Password should be atleast 6 characters"));
            return false;
          }
          return true;
        },
      },
      {
        name: "field_nombre",
        label: i18n.t("First Name"),
        group: 2,
        required: true,
        type: "txt",
      },
      {
        name: "field_apellidos",
        label: i18n.t("Surname"),
        group: 2,
        required: true,
        type: "txt",
      },
      {
        name: "field_perfil_de_usuario",
        label: i18n.t("User Profile"),
        group: 3,
        type: "select",
        required: true,
        items: [
          {label: i18n.t("Resident"), value: "residente"},
          {label: i18n.t("Tourist"), value: "turista"},
        ],
        value: "residente",
      },
      {
        name: "field_rango_de_edades",
        label: i18n.t("Age Range"),
        group: 3,
        type: "select",
        required: true,
        items: [
          {label: "0-20", value: "edad1"},
          {label: "21-30", value: "edad2"},
          {label: "31-40", value: "edad3"},
          {label: "41-50", value: "edad4"},
          {label: "51-60", value: "edad5"},
          {label: "61-70", value: "edad6"},
          {label: "71-80", value: "edad7"},
          {label: "81+", value: "edad8"},
        ],
        value: "edad1",
      },
      {
        name: "field_tipo_de_usuario",
        label: i18n.t("User Type"),
        group: 3,
        type: "select",
        required: true,
        items: [
          {label: i18n.t("Friends"), value: "amigos"},
          {label: i18n.t("Family"), value: "familia"},
          {label: i18n.t("Individual"), value: "individual"},
          {label: i18n.t("Partner"), value: "pareja"},
        ],
        value: "amigos",
      },
      {
        name: "field_tipo_de_viaje",
        label: i18n.t("Trip Type"),
        group: 3,
        type: "select",
        required: true,
        items: [
          {label: i18n.t("Culture"), value: "cultura"},
          {label: i18n.t("Gastronomic"), value: "gastronomico"},
          {label: i18n.t("Business"), value: "negocios"},
        ],
        value: "cultura",
      },
    ]),
  );
  useEffect(() => {
    navigation.setOptions({
      headerShown: true,
      headerTitle: i18n.t("Register"),
      headerStyle: {
        backgroundColor: "#fff",
        elevation: 0,
        shadowOpacity: 0,
        borderBottomWidth: 0,
        paddingHorizontal: 10,
      },
      headerTitleAlign: "center",
      headerTintColor: "#1a1a1a",
      headerTitleStyle: {fontWeight: "bold", fontSize: 17},
      headerLeft: function headerLeft() {
        return (
          <TouchableHighlight
            style={{padding: 10, borderRadius: 3}}
            underlayColor="#e7e7e7"
            onPress={() => props.navigation.openDrawer()}
          >
            <FontAwesome5 name="align-left" size={17} color="black" />
          </TouchableHighlight>
        );
      },
    });
  }, []);
  async function handleSubmit(data: FormData) {
    // console.log(JSON.stringify(data));
    dispatch({type: "LOADING"});
    const result = await UserModel.register(data);
    if (result) {
      dispatch({type: "SUCCESS"});
      alert(i18n.t("Thank You!, Your account has been successfully created"));
      navigation.navigate("Login");
    } else {
      dispatch({type: "FAILED"});
    }
  }
  return (
    <ScrollView showsVerticalScrollIndicator={false}>
      <View style={styles.container}>
        {state.ready && (
          <FormComponent
            formInputs={formRef.current.getForm()}
            title={i18n.t("Register New User")}
            submitText={i18n.t("register")}
            onSubmit={handleSubmit}
            loading={state.loading}
            requiredMessage={i18n.t("Field is Required")}
          />
        )}
        {state.loading && (
          <View style={{justifyContent: "center"}}>
            <ActivityIndicator color="blue" size="large" />
            <Text
              style={{
                marginVertical: 10,
                fontSize: 20,
                fontWeight: "600",
                color: "#ccc",
                textAlign: "center",
                fontFamily: "Montserrat_400Regular",
              }}
            >
              {`${i18n.t("Creating Account, Please Wait")}...`}
            </Text>
          </View>
        )}
        {state.success && (
          <View style={{justifyContent: "center"}}>
            <Text
              style={{
                marginVertical: 10,
                fontSize: 20,
                fontWeight: "600",
                color: "#ccc",
                textAlign: "center",
                fontFamily: "Montserrat_400Regular",
              }}
            >
              {i18n.t("Account Created Successfully!")}
            </Text>
          </View>
        )}
        {state.failed && (
          <View style={{justifyContent: "center"}}>
            <Text
              style={{
                marginVertical: 10,
                fontSize: 20,
                fontWeight: "600",
                color: "#ccc",
                textAlign: "center",
                fontFamily: "Montserrat_400Regular",
              }}
            >
              {i18n.t("Account Creation Failed, Please try again later")}
            </Text>
          </View>
        )}
      </View>
    </ScrollView>
  );
}

const styles = StyleSheet.create({
  container: {
    paddingHorizontal: "5%",
    backgroundColor: "#fbfbfb",
    flexGrow: 1,
  },
});

In Android the registration form looks good, but in iOS the items are out of their boxes... I don't know where is the problem, I hope someone could help me.

1 Answers

Here is the Picker style file.

    import React, {useState} from "react";
import {Text, View} from "react-native";
import {Picker} from "@react-native-picker/picker";

import type {FormSelectFieldProps} from "./types";

export default function FormSelectInput(props: FormSelectFieldProps) {
  const {input, styles} = props;
  const [isValid, setisValid] = useState(
    !input.required || Boolean(input.value),
  );
  const [errorMessage, setErrorMessage] = useState("");
  function onChangeFormValue(value: string) {
    let valid = isValid;
    if (input.required && !value) {
      valid = false;
      setErrorMessage(props.requiredMessage);
    } else if (input.validatation && value) {
      const validation = input.validatation(value, setErrorMessage);
      valid = validation;
      if (valid) {
        setErrorMessage("");
      }
    } else {
      valid = true;
      setErrorMessage(null);
    }
    setisValid(valid);
    input.value = value;
    props.onChangeObject(input.group, props.index, input.name, valid, input);
  }
  function ValidationErrorComponent() {
    if (errorMessage) {
      return (
        <View
          style={{
            flexDirection: "row",
            alignItems: "center",
            marginTop: 10,
          }}
        >
          <Text style={styles.errorMessage}>{errorMessage}</Text>
        </View>
      );
    } else {
      return null;
    }
  }
  return (
    <View style={styles.formInput}>
      <Text style={styles.inputLabel}>{input.label}:</Text>
      <View style={styles.input}>
        {props.input.items.length > 0 && (
          <Picker
            selectedValue={input.value}
            style={{height: 30}}
            onValueChange={(value) => onChangeFormValue(value)}
          >
            {input.items.map((type, i) => (
              <Picker.Item key={i} label={type.label} value={type.value} />
            ))}
          </Picker>
        )}
      </View>
      <ValidationErrorComponent />
    </View>
  );
}
Related