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 aStack.Navigator
, but removing the modal presentation style doesn't fix the issue. - I have tried setting
automaticallyAdjustContentInsets={false}
andcontentInsetAdjustmentBehavior="automatic"
onKeyboardAwareScrollView
, 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.