Home > OS >  KeyboardAwareScrollView causes jitter
KeyboardAwareScrollView causes jitter

Time:10-18

I am facing an issue which I can't seem to resolve. I am fairly new to React Native, but have experience with building iOS apps using Swift.

Currently, I am trying to create a pretty basic form, I am using KeyboardAwareScrollView to handle the keyboard showing up. With only two inputfields, this seems to work just fine. But as soon as there is a larger form, it doesn't seem to do so well.

You can see what's happening here: https://sendvid.com/ionrighs As you can see, as soon as I scroll all the way down, there is a jitter, some shakiness to the entire screen. I then can't easily scroll anymore, and when I finally am able to get back to the top, the jitter appears there too.

I have no idea why this is happening. All relevant code:

import React from 'react';
import { useState } from 'react';
import { Alert, TouchableWithoutFeedback, StatusBar, Dimensions, Pressable, Image, SafeAreaView, Keyboard, StyleSheet, Text, View, Button as RNButton } from 'react-native';
import { KeyboardAwareScrollView } from 'react-native-keyboard-aware-scroll-view';

import { Button, InputField, ErrorMessage } from '../components';

export default function SignupScreen({ navigation }) {
  const [email, setEmail] = useState('');
  const [phoneNumber, setPhoneNumber] = useState('');
  const [password, setPassword] = useState('');
  const [repeatPassword, setRepeatPassword] = useState('');
  const [firstName, setFirstName] = useState('');
  const [lastName, setLastName] = useState('');
  const [passwordVisibility, setPasswordVisibility] = useState(true);
  const [repeatPasswordVisibility, setRepeatPasswordVisibility] = useState(true);
  const [rightIcon, setRightIcon] = useState('eye');
  const [repeatRightIcon, setRepeatRightIcon] = useState('eye');
  const [signupError, setSignupError] = useState('');

  return (
    <View style={styles.container}>
    <TouchableWithoutFeedback
          onPress={Keyboard.dismiss}
          accessible={false}>
    <View style={{ flex: 1, backgroundColor: "white" }}>
    <KeyboardAwareScrollView
          keyboardShouldPersistTaps="handled"
          keyboardOpeningTime={0}
          alwaysBounceHorizontal={false}
          alwaysBounceVertical={false}
          showsHorizontalScrollIndicator={false}
          showsVerticalScrollIndicator={false}
          enableOnAndroid>
      <SafeAreaView>
      <StatusBar
            backgroundColor="transparent"
            barStyle="dark-content"
            hidden={false}
            translucent
          />
          
          <View style={styles.registerContainer}>
            <View style={styles.registerContent}>

                <InputField
                    labelText="Field 1"
                    inputStyle={{
                    fontSize: 14
                    }}
                    containerStyle={{
                    backgroundColor: '#fff',
                    }}
                    // leftIcon='email'
                    autoCapitalize='words'
                    keyboardType='default'
                    textContentType='givenName'
                    // autoFocus={true}
                    value={firstName}
                    onChangeText={text => setFirstName(text)}
                />

                <InputField
                    labelText="Field 2"
                    inputStyle={{
                    fontSize: 14
                    }}
                    containerStyle={{
                    backgroundColor: '#fff',
                    }}
                    // leftIcon='email'
                    autoCapitalize='words'
                    keyboardType='default'
                    textContentType='familyName'
                    // autoFocus={true}
                    value={lastName}
                    onChangeText={text => setLastName(text)}
                />

                <InputField
                    labelText="Field 3"
                    inputStyle={{
                    fontSize: 14
                    }}
                    containerStyle={{
                    backgroundColor: '#fff',
                    }}
                    // leftIcon='email'
                    autoCapitalize='none'
                    keyboardType='email-address'
                    textContentType='emailAddress'
                    // autoFocus={true}
                    value={email}
                    onChangeText={text => setEmail(text)}
                />

                <InputField
                    labelText="Field 4"
                    inputStyle={{
                    fontSize: 14
                    }}
                    containerStyle={{
                    backgroundColor: '#fff',
                    }}
                    // leftIcon='email'
                    autoCapitalize='none'
                    keyboardType='phone-pad'
                    textContentType='telephoneNumber'
                    // autoFocus={true}
                    value={phoneNumber}
                    onChangeText={text => setPhoneNumber(text)}
                />

                <InputField
                    labelText="Field 5"
                    inputStyle={{
                    fontSize: 14
                    }}
                    containerStyle={{
                    backgroundColor: '#fff',
                    }}
                    // leftIcon='lock'
                    autoCapitalize='none'
                    autoCorrect={false}
                    secureTextEntry={passwordVisibility}
                    textContentType='password'
                    rightIcon={rightIcon}
                    value={password}
                    onChangeText={text => setPassword(text)}
                    handlePasswordVisibility={handlePasswordVisibility}
                />

                <InputField
                    labelText="Field 6"
                    inputStyle={{
                    fontSize: 14
                    }}
                    containerStyle={{
                    backgroundColor: '#fff',
                    }}
                    // leftIcon='lock'
                    autoCapitalize='none'
                    autoCorrect={false}
                    secureTextEntry={passwordVisibility}
                    textContentType='password'
                    rightIcon={rightIcon}
                    value={password}
                    onChangeText={text => setPassword(text)}
                    handlePasswordVisibility={handlePasswordVisibility}
                />

                <InputField
                    labelText="Field 7"
                    inputStyle={{
                    fontSize: 14
                    }}
                    containerStyle={{
                    backgroundColor: '#fff',
                    }}
                    // leftIcon='lock'
                    autoCapitalize='none'
                    autoCorrect={false}
                    secureTextEntry={passwordVisibility}
                    textContentType='password'
                    rightIcon={rightIcon}
                    value={password}
                    onChangeText={text => setPassword(text)}
                    handlePasswordVisibility={handlePasswordVisibility}
                />

                <InputField
                    labelText="Field 8"
                    inputStyle={{
                    fontSize: 14
                    }}
                    containerStyle={{
                    backgroundColor: '#fff',
                    }}
                    // leftIcon='lock'
                    autoCapitalize='none'
                    autoCorrect={false}
                    secureTextEntry={passwordVisibility}
                    textContentType='password'
                    rightIcon={rightIcon}
                    value={password}
                    onChangeText={text => setPassword(text)}
                    handlePasswordVisibility={handlePasswordVisibility}
                />

                <InputField
                    labelText="Field 9"
                    inputStyle={{
                    fontSize: 14
                    }}
                    containerStyle={{
                    backgroundColor: '#fff',
                    }}
                    // leftIcon='lock'
                    autoCapitalize='none'
                    autoCorrect={false}
                    secureTextEntry={passwordVisibility}
                    textContentType='password'
                    rightIcon={rightIcon}
                    value={password}
                    onChangeText={text => setPassword(text)}
                    handlePasswordVisibility={handlePasswordVisibility}
                />

                <InputField
                    labelText="Field 10"
                    inputStyle={{
                    fontSize: 14
                    }}
                    containerStyle={{
                    backgroundColor: '#fff',
                    }}
                    // leftIcon='lock'
                    autoCapitalize='none'
                    autoCorrect={false}
                    secureTextEntry={passwordVisibility}
                    textContentType='password'
                    rightIcon={rightIcon}
                    value={password}
                    onChangeText={text => setPassword(text)}
                    handlePasswordVisibility={handlePasswordVisibility}
                />

                <InputField
                    labelText="Field 11"
                    inputStyle={{
                    fontSize: 14
                    }}
                    containerStyle={{
                    backgroundColor: '#fff',
                    }}
                    // leftIcon='lock'
                    autoCapitalize='none'
                    autoCorrect={false}
                    secureTextEntry={passwordVisibility}
                    textContentType='password'
                    rightIcon={rightIcon}
                    value={password}
                    onChangeText={text => setPassword(text)}
                    handlePasswordVisibility={handlePasswordVisibility}
                />

                <InputField
                    labelText="Field 12"
                    inputStyle={{
                    fontSize: 14
                    }}
                    containerStyle={{
                    backgroundColor: '#fff',
                    }}
                    // leftIcon='lock'
                    autoCapitalize='none'
                    autoCorrect={false}
                    secureTextEntry={passwordVisibility}
                    textContentType='password'
                    rightIcon={rightIcon}
                    value={password}
                    onChangeText={text => setPassword(text)}
                    handlePasswordVisibility={handlePasswordVisibility}
                />

                <InputField
                    labelText="Field 13"
                    inputStyle={{
                    fontSize: 14
                    }}
                    containerStyle={{
                    backgroundColor: '#fff',
                    }}
                    // leftIcon='lock'
                    autoCapitalize='none'
                    autoCorrect={false}
                    secureTextEntry={passwordVisibility}
                    textContentType='password'
                    rightIcon={rightIcon}
                    value={password}
                    onChangeText={text => setPassword(text)}
                    handlePasswordVisibility={handlePasswordVisibility}
                />

                <InputField
                    labelText="Field 14"
                    inputStyle={{
                    fontSize: 14
                    }}
                    containerStyle={{
                    backgroundColor: '#fff',
                    }}
                    // leftIcon='lock'
                    autoCapitalize='none'
                    autoCorrect={false}
                    secureTextEntry={passwordVisibility}
                    textContentType='password'
                    rightIcon={rightIcon}
                    value={password}
                    onChangeText={text => setPassword(text)}
                    handlePasswordVisibility={handlePasswordVisibility}
                />

                <InputField
                    labelText="Field 15"
                    inputStyle={{
                    fontSize: 14
                    }}
                    containerStyle={{
                    backgroundColor: '#fff',
                    }}
                    // leftIcon='lock'
                    autoCapitalize='none'
                    autoCorrect={false}
                    secureTextEntry={repeatPasswordVisibility}
                    textContentType='password'
                    repeatRightIcon={repeatRightIcon}
                    value={repeatPassword}
                    onChangeText={text => setRepeatPassword(text)}
                    handleRepeatPasswordVisibility={handleRepeatPasswordVisibility}
                />

                {/* {signupError ? <ErrorMessage error={signupError} visible={true} /> : null} */}

                <Button
                    onPress={onHandleSignup}
                    backgroundColor='#f57c00'
                    title='Button'
                    tileColor='#fff'
                    titleSize={20}
                    containerStyle={{
                    marginBottom: 20
                    }}
                />
                {/* <RNButton
                    onPress={() => navigation.navigate('Login')}
                    title='Go to Login'
                    color='red'
                /> */}
            </View>
        </View>
      </SafeAreaView>
    </KeyboardAwareScrollView>
    </View>
    </TouchableWithoutFeedback>
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
    // paddingTop: 50,
    // paddingHorizontal: 12
  },
  title: {
    fontSize: 24,
    fontWeight: '600',
    color: '#fff',
    alignSelf: 'center',
    // paddingBottom: 24
  },
  registerContainer: {
    width: '100%',
    backgroundColor: '#fff',
    alignItems: 'center',
    paddingTop: Dimensions.get('window').width * 0.1,
  },
  registerContent: {
    width: '80%',
    backgroundColor: 'white',
  },
  labelText: {
    fontSize: 16,
    color: '#808080',
    marginBottom: 10,
  },
});

A couple of things worth mentioning:

  • The screen is presented using CardStyleInterpolators.forVerticalIOS in a Stack.Navigator, but removing the modal presentation style doesn't fix the issue.
  • I have tried setting automaticallyAdjustContentInsets={false} and contentInsetAdjustmentBehavior="automatic" on KeyboardAwareScrollView, no luck.
  • Trying to use the keyboard in any of the form fields is a mess. I can't tap the inputfields, the keyboard almost never appears, and when it does, it seems to be stuck, so I can't fill out the form.

Does anybody have any idea how I can fix this?

CodePudding user response:

Instead of using KeyboardAwareScrollView, I would try using React Native's Core Component KeyboardAvoidingView. It should be a lot faster and still accomplish what you are trying to do. It should work if you interchange the two components in your code.

Source: https://reactnative.dev/docs/keyboardavoidingview

CodePudding user response:

I recreated everything and left out all elements to find the cause. It was <SafeAreaView>, apparently it's conflicting with the scrollview.

  • Related