react-native-keyboard-controller
react-native-keyboard-controller copied to clipboard
KeyboardAvoidingView does not work inside Modals if "prefer Cross-Fade Transitions" are enabled
Describe the bug The KeyboardAvoidingView is not expanding
Code snippet
import React, { useState } from "react";
import {
Modal,
StyleSheet,
Text,
TextInput,
TouchableOpacity,
View,
} from "react-native";
import { ScrollView } from "react-native-gesture-handler";
import { KeyboardAvoidingView } from "react-native-keyboard-controller";
import { useSafeAreaInsets } from "react-native-safe-area-context";
import type { ViewProps } from "react-native-svg/lib/typescript/fabric/utils";
const styles = StyleSheet.create({
flex1: { flex: 1 },
flexGrow1: { flexGrow: 1 },
heading: {
color: "black",
fontSize: 36,
marginBottom: 48,
fontWeight: "600",
},
inner: {
padding: 24,
flex: 1,
justifyContent: "space-between",
},
textInput: {
height: 45,
borderColor: "#000000",
borderWidth: 1,
borderRadius: 10,
marginBottom: 36,
paddingLeft: 10,
},
button: {
marginTop: 12,
height: 45,
borderRadius: 10,
backgroundColor: "rgb(40, 64, 147)",
justifyContent: "center",
alignItems: "center",
},
text: {
fontWeight: "500",
fontSize: 16,
color: "white",
},
backgroundColorRed: {
backgroundColor: "red",
},
});
function C() {
return (
<KeyboardAvoidingView
behavior="padding"
contentContainerStyle={styles.flex1 as ViewProps["style"]}
keyboardVerticalOffset={100}
style={styles.flex1}
testID="keyboard_avoiding_view.container"
>
<ScrollView
alwaysBounceVertical={false}
automaticallyAdjustsScrollIndicatorInsets={false}
contentContainerStyle={styles.flexGrow1}
contentInset={{ bottom: 30 }}
keyboardShouldPersistTaps="handled"
scrollEventThrottle={300}
scrollIndicatorInsets={{
right: 1,
bottom: 30,
}}
style={styles.flex1}
>
<View style={styles.inner}>
<Text style={styles.heading}>Header</Text>
<View>
<TextInput
placeholder="Username"
placeholderTextColor="#7C7C7C"
style={styles.textInput}
testID="keyboard_avoiding_view.username"
/>
<TextInput
secureTextEntry
placeholder="Password"
placeholderTextColor="#7C7C7C"
style={styles.textInput}
testID="keyboard_avoiding_view.password"
/>
</View>
<TouchableOpacity
style={styles.button}
testID="keyboard_avoiding_view.submit"
>
<Text style={styles.text}>Submit</Text>
</TouchableOpacity>
</View>
</ScrollView>
</KeyboardAvoidingView>
);
}
export default function KeyboardAvoidingViewExample() {
const [visible, setVisible] = useState(false);
const insets = useSafeAreaInsets();
return (
<View style={{ flex: 1 }}>
<TouchableOpacity style={styles.button} onPress={() => setVisible(true)}>
<Text style={styles.text}>Open</Text>
</TouchableOpacity>
<C />
<Modal visible={visible}>
<View
style={[
styles.flex1,
{ paddingTop: insets.top },
styles.backgroundColorRed,
]}
>
<TouchableOpacity
style={styles.button}
onPress={() => setVisible(false)}
>
<Text style={styles.text}>Close</Text>
</TouchableOpacity>
<C />
</View>
</Modal>
</View>
);
}
Repo for reproducing https://github.com/buschco/react-native-keyboard-controller
To Reproduce Steps to reproduce the behavior:
- Check out https://github.com/buschco/react-native-keyboard-controller or copy paste code from above
- Goto "Settings" -> "Accessibility" -> "Motion"
- Enable "Reduce Motion"
- Enable "Prefer Cross-Fade Transitions"
- Click on one TextInput and see working KeyboardAvoidingView
- Click on "Open" and the Screen should turn red now
- Click on one TextInput and see not working KeyboardAvoidingView
Screenshots
https://github.com/user-attachments/assets/9db92d81-dcb0-4275-96cf-33ba7bfbf12b
- Desktop: macOS Version 26.0.1 (25A362)
- Device: iPhone 16 Pro
- OS: iOS 26.0
- RN version: 0.78
- RN architecture: new fabric
- JS engine: Hermes
- Library version: 1.18.6
For more context: without "prefer Cross-Fade" transitions it also doesn't work (it's not animating, sometimes in the end KeyboardAvoidingView has incorrect frame)
https://github.com/user-attachments/assets/b4455ced-a09f-42d7-8c1e-ff9766dcae9d
Still reproducible on iOS 26.1, but it's reproducible even without modal 😲