expo: Expo SDK 23 doesn't support KeyboardAvoidingView/KeyboardAwareScrollView - TextInput hidden when keyboard visible

Original issue: https://github.com/GeekyAnts/NativeBase/issues/1418#issuecomment-349586972

package.json

{
  "main": "node_modules/expo/AppEntry.js",
  "private": true,
  "scripts": {
    "test": "node ./node_modules/jest/bin/jest.js --watch"
  },
  "jest": {
    "preset": "jest-expo"
  },
  "dependencies": {
    "@expo/samples": "2.1.1",
    "@expo/vector-icons": "^6.2.1",
    "expo": "^23.0.0",
    "firebase": "^4.6.2",
    "native-base": "^2.3.3",
    "react": "16.0.0",
    "react-native": "https://github.com/expo/react-native/archive/sdk-23.0.0.tar.gz",
    "react-native-datepicker": "^1.6.0",
    "react-navigation": "^1.0.0-beta.19",
    "react-redux": "^5.0.6",
    "redux": "^3.7.2",
    "redux-logger": "^3.0.6",
    "redux-thunk": "^2.2.0"
  },
  "devDependencies": {
    "jest-expo": "^23.0.0"
  }
}

Expected behaviour

With KeyboardAwareScrollView / Content (from native-base, etc.).

  1. Auto-Scrolling should happen when I type an input on lower half of screen.
  2. It is possible to scroll manually to make the input visible.

Actual behaviour

  1. No auto-scrolling happens. Both with Asus ZenUI keyboard and Google Gboard.
  2. It’s not possible to scroll manually to make the input visible. (see below for workaround)

Wrapping the Input/Item with KeyboardAvoidingView does not work either.

Input:

image

is obscured:

image

Steps to reproduce (code snippet or screenshot)

Test case : https://github.com/ceefour/keyboardavoider

      <Container>
        <Content>
          <Form>
             ...other <Item>s...
            <Item stackedLabel>
              <Label>Pekerjaan (lainnya)</Label>
              <Input value={this.state.userProfile.employment_other}
                onChangeText={(text) => this.setState({userProfile: {...this.state.userProfile, employment_other: text}})}/>
            </Item>
          </Form>
        </Content>
      </Container>

Tried using: <Content contentContainerStyle={{flex: 1}}> but made the content squashed.

Using @Andr3wHur5t’s <KeyboardSpacer/> (as @samarhaider suggests https://github.com/GeekyAnts/NativeBase/issues/534#issuecomment-344689283) only allows scrolling manually when keyboard is visible. However, auto-scroll still does not occur even with KeyboardSpacer :

videotogif_2017 12 05_04 26 44

Is the bug present in both ios and android or in any one of them?

Only tested with Android 7.0 and Expo SDK 23. Issue did not occur with expo 19.0.1.

About this issue

  • Original URL
  • State: closed
  • Created 7 years ago
  • Comments: 25 (3 by maintainers)

Commits related to this issue

Most upvoted comments

add something like this to your app.json if you want this component to work with default props:

    "androidStatusBar": {
      "backgroundColor": "#C2185B",
    },

that makes it work as expected. the reason is that the status bar is translucent by default in expo but not in react-native. if someone wants to add more info to docs that would be appreciated!

keyboard

I got it working with

<KeyboardAvoidingView behavior="padding">
    ...
</KeyboardAvoidingView>

Yes, Put Content inside KeyboardAwareScrollView <Container>

    <KeyboardAwareScrollView
        extraScrollHeight={100}
        enableOnAndroid={true} 
        keyboardShouldPersistTaps='handled'
        >
        <Content padder >
          <Logo message={message} />
          <Form style={{ margin: 20 }}>
            <Item >
              {/* <Icon active name='md-call' />                */}
              <Input
                style={{color: "#FFF", paddingLeft: 40}} 
                placeholder="Enter your email address"
                value={this.props.email}
                onChangeText={this.onemailChanged}
                keyboardType="email-address"
                disabled={this.props.loading}
                autoCorrect={false}
                autoCapitalize={'none'}
                returnKeyType={'done'}
              />
            </Item>

          </Form>
        </Content>
      </KeyboardAwareScrollView>   
  </Container>

I was able to reproduce the issue on this Snack.

https://snack.expo.io/r1A0kaj-M

Rather than wrapping <Content /> in a <KeyboardAwareScrollView />, I think you can simply add the enableOnAndroid prop to the <Content />. NativeBase passes it along.

  <Container>
    <Content enableOnAndroid>
      <Form>
        <Item>
          <Input />
        </Item>
      </Form>
    </Content>
  </Container>

Side note: androidStatusBar option in app.json didn’t solve it for me. I’m on expo 32 currently.

for anyone who’s looking for a sample code… the trick is to actually not use keyboardavoidingview with the status bar trick

      <Container style={styles.background}>
        <Content>
          <Form>
            <Item floatingLabel>
              <Label>Email</Label>
              <Input value={this.state.email} onChangeText={email => this.setState({email})}/>
            </Item>
          </Form>
        </Content>
      </Container>

@pandapaul awesome, your tricks works , had i been looking for this issue one hour earlier I wouldn’t have seen your response 😃

Still investigating, but just in case my experience helps someone in the future:

I found that if I was using NativeBase’s <Content> then this behaviour did not work as I expected on Android (i.e the keyboard often covered the input I was interacting with). But, if I swapped it out for <KeyboardAwareScrollView enableOnAndroid>then everything worked as expected.

I’m not sure why nativebase (“cross-platform UI components”) doesn’t include the enableOnAndroid prop which makes this work on Android. I wondered if this was because the default expectation on Android is for the platform to pan the contents of the window (which in most cases probably results in the input being visible without any need to listen to keyboard events in the <ScrollView>).

However, as I understand it, expo eject produces an Android project with a manifest configured with android:windowSoftInputMode="adjustResize". This means the <ScrollView> will be resized, but I’m not experienced enough with react-native and/or Android to predict whether that will trigger any scrolling.

If it doesn’t, this probably explains why using a <Content> on an Expo project will result in the keyboard covering inputs on Android - the <ScrollView> isn’t panning, and <KeyboardAwareScrollView> isn’t enabled.

@gerardo15 I suspect this is why nesting <KeyboardAwareScrollView>s “works” in the example provided by @samarhaider above - they’re including enableOnAndroid, which <Content> does not.

P.S @SupriyaKalghatgi I’d love someone who probably actually understands the complexity here to check my understanding 😄

@samarhaider How does this work? if you look at Content> from Native Base, it is a KeyboardAwareScrollView

so basically you are placing a KeyboardAwareScrollView inside a KeyboardAwareScrollView?

@brentvatne That seems to work great on Android. However, absolutely nothing happens on iOS as far as I can tell, no position adjustment for keyboard events. Is there a similar trick to get this to work on iOS?

@brentvatne @mauroporrasp Yeah, makes me wondering: what if the status bar is hidden entirely, i.e. a full screen app ?

THANK YOU @mario-subotic ! Your hard work is really appreciated!

Your Snack also reproduces on Expo 21 (the oldest supported by Snack).