react-native: KeyboardAvoidingView with behavior="height" doesn't resize back on keyboard close

Description

When using the KeyboardAvoidingView with behavior set to height it works correctly the first time you open the keyboard, but after keyboard is dismissed it doesn’t return to it’s original position.

tnyozqi5fe

Recreation: https://snack.expo.io/rJYAymwy-

The code below can be used to recreate this problem:

<View style={{flex: 1, backgroundColor: "blue"}}>
	<KeyboardAvoidingView behavior="height"  style={{ backgroundColor: "green", paddingTop: 22, flex: 1, justifyContent: 'center'}}>
	    <View>
	          <TextInput style={{height: 30, backgroundColor: "red"}} />
	    </View>
	</KeyboardAvoidingView>
</View>

Additional Information

  • React Native version: 0.43.4
  • Development Operating System: MacOS
  • Dev tools: This was shown on the IOS simulator but the problem also occurs on android

About this issue

  • Original URL
  • State: closed
  • Created 7 years ago
  • Reactions: 89
  • Comments: 19 (2 by maintainers)

Commits related to this issue

Most upvoted comments

Issue is still there in React Native 0.44.2

For those running into this issue you can find a work-around here https://gist.github.com/steven89/f7aedca683deee6ee8211399e94cd583

The issue is related to onLayout mechanism (rendered height is calculated from layout’s height):

  • onLayout is not called when the keyboard is dismissed, because the keyboard is not constraining the component’s layout anymore.
  • onLayout is called after render, so even if it was actually called, the computed height value in render would not be correct.

The work-around I have found to make it work is to fixate the layout height to its initial value before render (componentWillUpdate).

A real fix would be to find a way to call onLayout when keyboard is dismissed and before rendering. Due to the source of the issue, I wouldn’t expect a fix anytime soon.

If you want to take a look, the KeyboardAvoidingView’s code is there: https://github.com/facebook/react-native/blob/master/Libraries/Components/Keyboard/KeyboardAvoidingView.js

behavior="padding" worked for us BUT since it is inside a ScrollView we get a huge padding at the bottom (almost same height as the contents) when we dismiss the keyboard (and while it is on). Any ideas?

This same question was asked on Stack Overflow

Edit: When I originally posted there was no answer, but now there is 🎉 KeyboardAvoidingView - Reset height when Keyboard is hidden

android:windowSoftInputMode="adjustResize" is doing the work for you though, and the thing about adding that to AndroidManifest is that it now applies keyboard avoiding behavior to all of your input fields, which you may not want. There should be a better way to handle keyboard avoiding behavior for different situations.

Same issue here, iOS 11, react native 0.50. Using behavior='padding' instead of behavior='height' does work for me, but might not be appropriate in your case.

I’ve created Android and iOS specific implementations for this and the result is that on both platforms the height is restored properly when the keyboard is dismissed.

See this gist here: https://gist.github.com/markoudev/c3f06afc5d88d1056859ecc01c2777bc (it’s in TypeScript, but you’ll get the gist (heh) of it).

Note that you have to set android:windowSoftInputMode="adjustResize" in AndroidManifest.xml for this to work.

@afilp try to put your KeyboardAvoidingView around the ScrollView.