I have a form wrapped inside a parent container (which is a KeyboardAvoidingView), and after adding the appropriate flex properties to center the form horizontally and vertically, the form does not center in either direction.
Here is the code for the parent container containing the form:
const AuthScreen = () => {
const [isSignup, setIsSignup] = useState(false)
return (
<SafeAreaView style={{flex: 1}}>
<PageContainer>
<ScrollView>
<KeyboardAvoidingView style={styles.keyboardAvoidingView} behavior={Platform.OS === "ios" ? "height" : undefined} keyboardVerticalOffset={100}>
<LoginForm />
</KeyboardAvoidingView>
</ScrollView>
</PageContainer>
</SafeAreaView>
)
}
const styles = StyleSheet.create({
keyboardAvoidingView: {
padding: 10,
alignItems: 'center',
justifyContent: 'center',
flex: 1,
}
})
export default AuthScreen
Here is the form (LoginForm) code. This is the form I expect to be centered:
const LoginForm = () => {
const [formState, dispatchFormState] = useReducer(reducer, initialState);
const inputChangedHandler = useCallback((id, value) => {
// Validate current input status
const validationResult = validateInput(id, value)
dispatchFormState({id, value, validationResult})
}, [dispatchFormState])
return (
<>
<Input errorText={formState.inputValidities["email"]} inputChanged={inputChangedHandler} id="email" placeholder="Email Address" />
<Input errorText={formState.inputValidities["password"]} inputChanged={inputChangedHandler} id="password" placeholder="Password" />
<SubmitButton title='Login' />
</>
)
}
const styles = StyleSheet.create({
})
export default LoginForm
The code for the **Input **component:
const Input = props => {
const {id, placeholder, inputChanged, errorText} = props
return <View style={styles.container}>
<View style={styles.inputContainer}>
<TextInput onChangeText={(text) => inputChanged(id, text)} placeholderTextColor="white" style={styles.input} placeholder={placeholder} />
</View>
{
errorText &&
<View style={styles.errorContainer}>
<Text style={{color: 'red'}}>{errorText[0]}</Text>
</View>
}
</View>
}
const styles = StyleSheet.create({
container: {
width: '100%',
marginTop: 32,
alignItems: 'center',
},
input: {
backgroundColor: colors.inputBgColor,
flex: 1,
paddingVertical: 6,
paddingHorizontal: 12,
letterSpacing: 0.3,
color: 'white'
},
inputContainer: {
width: '100%',
flexDirection: 'row',
alignItems: 'center',
},
errorContainer: {
alignItems: 'center',
marginTop: 10
}
})
export default Input
Could I get some ideas on why this form is not centering? Thank you.
2
Answers
The issue with your code might be related to the combination of using a
KeyboardAvoidingView
and theflex
property on the parent container. When usingKeyboardAvoidingView
and trying to center its content usingflex
, you might encounter unexpected behavior.Here’s a suggestion to fix the issue:
Remove the
flex: 1
from thekeyboardAvoidingView
style inAuthScreen
. This will prevent theKeyboardAvoidingView
from taking all the available space.Instead of using
alignItems: 'center'
andjustifyContent: 'center'
on thekeyboardAvoidingView
, apply these properties to theScrollView
and thePageContainer
components. This will center theKeyboardAvoidingView
within theScrollView
and thePageContainer
within theSafeAreaView
.Here’s the updated code for
AuthScreen
:Note that I added two new styles:
pageContainer
andscrollViewContent
, which handle the centering of the content within theSafeAreaView
andScrollView
, respectively.With this change, your
LoginForm
component should now be centered both horizontally and vertically.Use contentContainerStyle to apply style to the scroll view content container. Using
flexGrow: 1
allows children to grow when needed.