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

Created on 3 May 2017  路  19Comments  路  Source: facebook/react-native

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
Bug Help Wanted iOS Locked PR Submitted

Most helpful comment

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

All 19 comments

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

I'm seeing this in React Native version: 0.40.0

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

Having the same issue here.

+1

Same issue: keyboardVerticalOffset not fully removed. v0.45.0

I had similar problem. KeyboardAwareScrollView solved the problem for me.

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.

Same issue here. React Native 0.50.4.

And here I was messing with flex on 10 different places trying to figure out what exactly that I did was wrong.

We also exhibited this problem, with React Native 0.52.x

Using behavior="padding" was a viable workaround for our project too. /cc @MehmetBal

Yes along with behavior="padding" we also needed to use keyboardVerticalOffset={SizeOfYourLoginButton} to make the login button appear above the keyboard.

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?

still a problem on android

react: 16.2.0 => 16.2.0
react-native: 0.53.0 => 0.53.0

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.

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.

Here is a workaround to fix the leftover space issue after the keyboard is dismissed: https://stackoverflow.com/q/41616457/193210

@Lily418 mentioned this in a comment above, but there wasn't an answer at the time.

@afilp try to put your KeyboardAvoidingView around the ScrollView.

Was this page helpful?
0 / 5 - 0 ratings