The error is: RCTLayoutAnimationGroup expects timings to be in ms, not seconds
This occurs as I drag the keyboard downwards quickly. Sometimes it happens; sometimes it doesn't.
I am using a simple TextInput component, within a KeyboardAvoidingView
scrollTo()This is deprecated due to ambiguity (y before x), and SHOULD NOT BE USED.
This issue can be solved by using the keyboardDismissMode='on-drag' property on Scrollview and Content, which will make the keyboard to get disappear automatically on scrolling. Read our article on Why is React Native the best for Mobile App Development?
Adding bounces={false} to your ScrollView seems to solve the issue.
<ScrollView keyboardDismissMode="interactive" bounces={false}>
It changes the behaviour a bit as well but, the error doesn't seem to appear anymore.
I think if you wish to keep the 'bouncy' behaviour of the ScrollView, the best way would be to make the 'bounces' dependent on the keyboard show. When the keyboard is shown, the bounces is set to false. Have a look at my sample component:
export default class App extends Component<Props> {
constructor(){
super();
this.state = {
bounces: true
}
this.keyboardDidHideListener = Keyboard.addListener('keyboardDidHide', this._keyboardDidHide.bind(this));
this.keyboardDidShowListener = Keyboard.addListener('keyboardDidShow', this._keyboardDidShow.bind(this));
}
_keyboardDidShow(){
this.setState({bounces: false});
}
_keyboardDidHide(){
this.setState({bounces: true});
}
render() {
return (
<KeyboardAvoidingView style={styles.container} behavior="padding" enabled>
<ScrollView keyboardDismissMode="interactive" bounces={this.state.bounces}>
<TextInput
style={{height: 40, width: 150, borderColor: 'gray', borderWidth: 1}}
/>
</ScrollView>
</KeyboardAvoidingView>
);
}
}
EDIT:
A RNT hack would be to override the duration when it is less than 10(ms). For you it should be to change: node_modules/react-native/Libraries/Components/Keyboard/KeyboardAvoidingView.js method: scheduleLayoutAnimation change:
const {duration, easing, endCoordinates} = event;
to:
let {duration, easing, endCoordinates} = event;
and add:
if(duration < 10){
duration = 10;
}
inside the if (duration && easing) condition.
This will make sure the shortest duration is 1ms and never less, thus the duration is not going to be thrown anymore.
My KeyboardAvoidingView.js, _onKeyboardChange method looks something like this:
_onKeyboardChange = (event: ?KeyboardEvent) => {
if (event == null) {
this.setState({bottom: 0});
return;
}
let {duration, easing, endCoordinates} = event;
const height = this._relativeKeyboardHeight(endCoordinates);
if (this.state.bottom === height) {
return;
}
if (duration && easing) {
if(duration < 10){
duration = 10;
}
LayoutAnimation.configureNext({
duration: duration,
update: {
duration: duration,
type: LayoutAnimation.Types[easing] || 'keyboard',
},
});
}
this.setState({bottom: height});
};
EDIT 2:
I submitted an issue to RNT team, and opened a PR to them: https://github.com/facebook/react-native/pull/21858
EDIT 3: The fix was merged to react native master: https://github.com/facebook/react-native/commit/87b65339379362f9db77ae3f5c9fa8934da34b25
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With