11

I use react native to create a mobile app. I handle keyboard position in my screens by using KeyboardAvoidingView, SafeAreaView and ScrollView. I use this order to manage Keyboard position :

<KeyboardAvoidingView style={{ flex: 1 }} behavior="padding" enabled>
        <SafeAreaView>
          <ScrollView>
            <Header
              leftComponent={{
                icon: "cancel",
                color: "#fff",
                size: 30,
                onPress: () => navigate("Dashboard")
              }}
              centerComponent={{ text: "Ajouter une demande", style: { color: "#fff", fontSize: 18 } }}
              rightComponent={{
                icon: "help",
                color: "#fff",
                size: 30,
                fontWeight: "bold",
                onPress: () => Alert.alert("En cours de développement")
              }}
              backgroundColor="rgba(82, 159, 197, 1)"
              // outerContainerStyles={{ height: Platform.OS === "ios" ? 70 : 70 - 24 }}
              containerStyle={
                {
                  // marginTop: Platform.OS === "ios" ? 0 : 15
                }
              }
            />
            <View>
              <Input placeholder="INPUT WITH CUSTOM ICON" leftIcon={<Icon name="user" size={24} color="black" />} />
            </View>
          </ScrollView>
        </SafeAreaView>
      </KeyboardAvoidingView>

My question is : what's the best order to use those 3 components to avoid a best keyboard position

Khaled Boussoffara
  • 1,567
  • 2
  • 25
  • 53

3 Answers3

5

SafeAreaView only works with iOS. Therefore, it is assumed that you use the iOS. If your project is iOS, you can use KeyboardAwareScrollView.

SafeAreaView should be at the top because it covers the area of the screen.

KeyboardAwareScrollView Example

gifimage

Usage

import { KeyboardAwareScrollView } from 'react-native-keyboard-aware-scroll-view'
...
<SafeAreaView>
<KeyboardAwareScrollView>
  <View>
    <TextInput />
  </View>
</KeyboardAwareScrollView>
</SafeAreaView>
hong developer
  • 13,291
  • 4
  • 38
  • 68
1

Here is a re-usable component example without library and includes KeyboardAvoidingView, SafeAreaView and ScrollView. It also makes scrollview expand to full height.

import { KeyboardAvoidingView, SafeAreaView, ScrollView } from 'react-native';
import React from 'react';

const ScreenContainer = props => {
  const { children } = props;
  return (
    <SafeAreaView style={ { flex: 1 } }>
      <KeyboardAvoidingView
        behavior={ Platform.OS === 'ios' ? 'padding' : 'height' }
        style={ { flex: 1 } }
      >
        <ScrollView
          contentInsetAdjustmentBehavior="automatic"
          keyboardShouldPersistTaps="handled"
        >
          { children }
        </ScrollView>
      </KeyboardAvoidingView>
    </SafeAreaView>
  );
};

export default ScreenContainer;

Dylan w
  • 2,565
  • 1
  • 18
  • 30
  • I mapped an array of 20 TextInputs inside of children in your example and it didn't work. The scroll doesn't go below actual input I clicked on. – denistepp Jul 21 '21 at 15:56
0

Here is an another solution without the need of an external library such as react-native-keyboard-aware-scroll-view.

I made a ScreenWrapper component to handle the IOs issue:

import React, { ReactElement } from 'react';
import {
  KeyboardAvoidingView, Platform,
} from 'react-native';
import { SafeAreaView } from 'react-native-safe-area-context';

const ScreenWrapper = ({ children }: Props): ReactElement => {
  return (
    <SafeAreaView style={{ flex: 1 }}>
      {
        Platform.OS === 'ios'
          ? (
            <KeyboardAvoidingView style={{ flex: 1 }} behavior="padding">
              {children}
            </KeyboardAvoidingView>
          )
          : (
            <>
              {children}
            </>
          )
      }
    </SafeAreaView>
  );
};

export default ScreenWrapper;

As Android looks to make the things greatly without the KeyboardAvoidingView, I decided to use it only for IOs, it's simpler to manage.

I use the padding because it fits my need but you may want to change it.

I recommend to read this excellent blog post for more information. I created this wrapper thanks to it.

Soullivaneuh
  • 3,553
  • 3
  • 37
  • 71
  • I mapped an array of 20 `TextInput`s inside of `children` in your example and it didn't work. The scroll doesn't go below actual input I clicked on. – denistepp Jul 21 '21 at 15:56