Giter Club home page Giter Club logo

react-native-keyboard-aware-scroll-view's Introduction

react-native-keyboard-aware-scroll-view

A ScrollView component that handles keyboard appearance and automatically scrolls to focused TextInput.

Scroll demo

Supported versions

  • v0.4.0 requires RN>=0.48
  • v0.2.0 requires RN>=0.32.0.
  • v0.1.2 requires RN>=0.27.2 but you should use 0.2.0 in order to make it work with multiple scroll views.
  • v0.0.7 requires react-native>=0.25.0.
  • Use v0.0.6 for older RN versions.

Installation

Installation can be done through npm or yarn:

npm i react-native-keyboard-aware-scroll-view --save
yarn add react-native-keyboard-aware-scroll-view

Usage

You can use the KeyboardAwareScrollView, KeyboardAwareSectionList or the KeyboardAwareFlatList components. They accept ScrollView, SectionList and FlatList default props respectively and implement a custom high order component called KeyboardAwareHOC to handle keyboard appearance. The high order component is also available if you want to use it in any other component.

Import react-native-keyboard-aware-scroll-view and wrap your content inside it:

import { KeyboardAwareScrollView } from 'react-native-keyboard-aware-scroll-view'
<KeyboardAwareScrollView>
  <View>
    <TextInput />
  </View>
</KeyboardAwareScrollView>

Auto-scroll in TextInput fields

As of v0.1.0, the component auto scrolls to the focused TextInput 😎. For versions v0.0.7 and older you can do the following.

Programatically scroll to any TextInput

In order to scroll to any TextInput field, you can use the built-in method scrollToFocusedInput. Example:

_scrollToInput (reactNode: any) {
  // Add a 'scroll' ref to your ScrollView
  this.scroll.props.scrollToFocusedInput(reactNode)
}
<KeyboardAwareScrollView
  innerRef={ref => {
    this.scroll = ref
  }}>
  <View>
    <TextInput
      onFocus={(event: Event) => {
        // `bind` the function if you're using ES6 classes
        this._scrollToInput(ReactNative.findNodeHandle(event.target))
      }}
    />
  </View>
</KeyboardAwareScrollView>

Programatically scroll to any position

There's another built-in function that lets you programatically scroll to any position of the scroll view:

this.scroll.props.scrollToPosition(0, 0)

Register to keyboard events

You can register to ScrollViewResponder events onKeyboardWillShow and onKeyboardWillHide:

<KeyboardAwareScrollView
  onKeyboardWillShow={(frames: Object) => {
    console.log('Keyboard event', frames)
  }}>
  <View>
    <TextInput />
  </View>
</KeyboardAwareScrollView>

Android Support

First, Android natively has this feature, you can easily enable it by setting windowSoftInputMode in AndroidManifest.xml. Check here.

But if you want to use feature like extraHeight, you need to enable Android Support with the following steps:

  • Make sure you are using react-native 0.46 or above.
  • Set windowSoftInputMode to adjustPan in AndroidManifest.xml.
  • Set enableOnAndroid property to true.

Android Support is not perfect, here is the supported list:

Prop Android Support
viewIsInsideTabBar Yes
resetScrollToCoords Yes
enableAutomaticScroll Yes
extraHeight Yes
extraScrollHeight Yes
enableResetScrollToCoords Yes
keyboardOpeningTime No

API

Props

All the ScrollView/FlatList props will be passed.

Prop Type Description
innerRef Function Catch the reference of the component.
viewIsInsideTabBar boolean Adds an extra offset that represents the TabBarIOS height.
resetScrollToCoords Object: {x: number, y: number} Coordinates that will be used to reset the scroll when the keyboard hides.
enableAutomaticScroll boolean When focus in TextInput will scroll the position, default is enabled.
extraHeight number Adds an extra offset when focusing the TextInputs.
extraScrollHeight number Adds an extra offset to the keyboard. Useful if you want to stick elements above the keyboard.
enableResetScrollToCoords boolean Lets the user enable or disable automatic resetScrollToCoords.
keyboardOpeningTime number Sets the delay time before scrolling to new position, default is 250
enableOnAndroid boolean Enable Android Support

Methods

Use innerRef to get the component reference and use this.scrollRef.props to access these methods.

Method Parameter Description
getScrollResponder void Get ScrollResponder
scrollToPosition x: number, y: number, animated: bool = true Scroll to specific position with or without animation.
scrollToEnd animated?: bool = true Scroll to end with or without animation.
scrollIntoView element: React.Element<*>, options: { getScrollPosition: ?(parentLayout, childLayout, contentOffset) => { x: number, y: number, animated: boolean } } Scrolls an element inside a KeyboardAwareScrollView into view.

Using high order component

Enabling any component to be keyboard-aware is very easy. Take a look at the code of KeyboardAwareFlatList:

/* @flow */

import { FlatList } from 'react-native'
import listenToKeyboardEvents from './KeyboardAwareHOC'

export default listenToKeyboardEvents(FlatList)

The HOC can also be configured. Sometimes it's more convenient to provide a static config than configuring the behavior with props. This HOC config can be overriden with props.

/* @flow */

import { FlatList } from 'react-native'
import listenToKeyboardEvents from './KeyboardAwareHOC'

const config = {
  enableOnAndroid: true,
  enableAutomaticScroll: true
}

export default listenToKeyboardEvents(config)(FlatList)

The available config options are:

{
  enableOnAndroid: boolean,
  contentContainerStyle: ?Object,
  enableAutomaticScroll: boolean,
  extraHeight: number,
  extraScrollHeight: number,
  enableResetScrollToCoords: boolean,
  keyboardOpeningTime: number,
  viewIsInsideTabBar: boolean,
  refPropName: string,
  extractNativeRef: Function
}

License

MIT.

Author

Álvaro Medina Ballester <amedina at apsl.net>

Built with πŸ’› by APSL.

react-native-keyboard-aware-scroll-view's People

Contributors

alizbazar avatar alvaromb avatar chrisy-lili avatar cooptwostar avatar crash-- avatar daveiverson-pear avatar dependabot[bot] avatar djkmiles avatar doomsower avatar foxmicha avatar gaishimo avatar invig avatar iroachie avatar joeybaker avatar karlosq avatar luqiuyuan avatar mingjen avatar nik910 avatar orinamio avatar ozsirma avatar pietropizzi avatar piotrgrundas avatar rborn avatar sebasgarcep avatar slorber avatar stackia avatar swordsman-inaction avatar taichi-jp avatar vincentlanglet avatar yury avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

react-native-keyboard-aware-scroll-view's Issues

Android support?

Should this work for Android? I was having an issue with a view in iOS and Android and I put this component in place. It seemed to fix the iOS version, but the Android version still behaves the same (the keyboard covers the content in the ScrollView).

iOS broken on 0.2.0

Upgraded to 0.2.0 (which fixes some scrolling issues on Android) but now iOS is broken

screen shot 2016-08-25 at 10 03 00 pm

AutoFocus not working

It doesn't seem to work in 0.1.2.
When I set alwaysBounceHorizontal & alwaysBounceVertical as false, as in #35 (I faced the same issue),
it wouldn't autofocus, and when I manually scroll to the desired TextInput and dismiss the keyboard the scrollView is stuck at its position.
Is there a guideline or things to keep in mind with this? Most of the textinputs are hidden behind the keyboard in my case.

<KeyboardAwareScrollView> works as normal like <Scrollview>

this module works for me but intially when it renders it shows scrollbar, and behaves as like of scrollview. what is the purpose of behaving like scrollview? i only need scrolling view up when i input text in textfield. Give me some suggestion.

Cannot auto-scroll to TextInput

I am following the example to try auto-scroll to TextInput in ScrollView, however I got:

image

Any idea where I might go wrong?

Not working with Navigator

We tested this component with and without the RN Navigator component, and when we use it with the Navigator as a wrapper to all our views, the keyboard-aware stops working.
We are working on Android.
Any thoughts on this?

Allow extra height to be set via props

In the KeyboardAwareMixin.js const _KAM_EXTRA_HEIGHT = 75 is the default.
It is hardcoded and we have to manually change the extra height there, but will break with a new upgrade. Is there a way you can allow to set it via props? Something like this:
<KeyboardAwareScrollView extraHeight={120}?

RCTTextField is not a descendant of RCTShadowView

Hey!

Thanks for react-native-keyboard-aware-scroll-view! All works great apart from the issue in which all of the TextFields which are not contained within stop working. The error appears after the keyboard is presented :

img_4983

KeyboardAwareListView failed propType renderScrollComponent

When using the KeyboardAwareListView I get the following warning:

screen shot 2016-06-27 at 23 44 10

This happens because the propType renderScrollComponent is required in the RN ListView component.

I solved the warning by overriding the renderScrollComponent and marking is as not required in the KeyboardAwareListView component.

/* @flow */

import React, { PropTypes } from 'react'
import { ListView } from 'react-native'
import KeyboardAwareMixin from './KeyboardAwareMixin'

const KeyboardAwareListView = React.createClass({
  propTypes: {
    ...ListView.propTypes,
    viewIsInsideTabBar: React.PropTypes.bool,
    resetScrollToCoords: PropTypes.shape({
      x: PropTypes.number,
      y: PropTypes.number,
    }),
    renderScrollComponent: React.PropTypes.func, //Added this line
  },
  mixins: [KeyboardAwareMixin],

  componentWillMount: function () {
    this.setViewIsInsideTabBar(this.props.viewIsInsideTabBar)
    this.setResetScrollToCoords(this.props.resetScrollToCoords)
  },

  render: function () {
    return (
      <ListView
        ref='_rnkasv_keyboardView'
        keyboardDismissMode='interactive'
        contentInset={{bottom: this.state.keyboardSpace}}
        showsVerticalScrollIndicator={true}
        {...this.props}
      />
    )
  },
})

export default KeyboardAwareListView

Is this a valid solution?

Cannot read property 'addListener' of undefined

simulator screen shot jun 23 2016 1 06 25 am

I am getting this error while trying to use the KeyboardAwareScrollView component.
It seems the 'Keyboard' keyword in Keyboard.addListener is not defined or not recognized.
Has anyone else faced the error?
Any help appreciated.

Argument 0 (NSNumber) of RCTUIManager.measureLayout must not be null

Has anyone come across this error?

2016-05-15 15:22:25.758 [error][tid:com.facebook.react.ShadowQueue][RCTModuleMethod.m:58] Argument 0 (NSNumber) of RCTUIManager.measureLayout must not be null
2016-05-15 15:22:25.784 [error][tid:com.facebook.react.ShadowQueue][RCTModuleMethod.m:58] Argument 0 (<null>) of RCTUIManager.measureLayout could not be processed. Aborting method call.

I think I followed the instructions correctly. The error appears after I tap the textInput. I'm running React 0.14.5 and React Native 0.25.1.

Working with View + ScrollView

Hey,
here is my code related to #18 (comment)

I'm using the following structure

video.js

Posting extends from React.Component {

  constructor(props) {
    super(props);
}

_scrollToInput (event, reactNode) {
 this.refs.scroll.scrollToFocusedInput(event, reactNode)
}

render() {
  return 
    (<View>
     <Video/>
      <KeyboardAwareScrollView ref='scroll'>
        <CommentItem/>
        <CommentItem/>
        <TextInput onFocus={this._scrollToInput}/>
     </KeyboardAwareScrollView>
    </View>)
 }

}

If I click on the text input, reactNode is null. I'm using RN 0.25.1

android no UIManager.viewIsDescendantOf

The android version no UIManager.viewIsDescendantOf method. So
// Automatically scroll to focused TextInput
if (this.props.enableAutoAutomaticScroll) {
const currentlyFocusedField = TextInput.State.currentlyFocusedField()
if (!currentlyFocusedField) {
return
}
UIManager.viewIsDescendantOf(
currentlyFocusedField,
this.getScrollResponder().getInnerViewNode(),
(isAncestor) => {
if (isAncestor) {
this.scrollToFocusedInputWithNodeHandle(currentlyFocusedField)
}
}
)
}

this code has problem. How solve it?

Android dismisses keyboard on scroll

Using the latest version on RN 0.32:

When focusing on a text input that requires scrolling, it'll correctly readjust the position of the text input to above the keyboard, but then dismisses the keyboard. Strangely, if you tap on the text input again, the keyboard will pop up, but then dismiss itself after entering a single character. Then focusing on that text input again will allow you to write whatever you'd like.

Issue only seen on Android. Has anyone else seen this behavior?

Edit: Looking at the mixin some more, it seems the latest release only works on iOS - the keyboard events are never triggered on Android, and would throw an error if they were for using UIManager. Is there something needed for Android to keep the keyboard up - maybe in the manifest file?

Scroll view doesn't scroll when input is focused.

I have multiple inputs structured like the following, when I tap and focus on an input close to the bottom, I expect the view to scroll to the focused input because the input is underneath the keyboard. But the scroll view doesn't do anything. Am I missing something here? Do I need to call anything from onFocus of each <TextInput>?

    <KeyboardAwareScrollView viewIsInsideTabBar={true}
                                     keyboardShouldPersistTaps={true}>
            <View>
                <View>
                    <TextInput>...</TextInput>
                </View>
                <View>
                    <TextInput>...</TextInput>
                </View>
                <View>
                    <TextInput>...</TextInput>
                </View>
            </View>
    </KeyboardAwareScrollView>

tag #? is not a descendant of <RCTShadowView

Hi all, firstly, thanks for the component and for your time of maintaining it.

I'm using native-base which uses react-native-keyboard-aware-scroll-view. I was aware of the issue #25 and was waiting for the new react-native and react-native-keyboard-aware-scroll-view versions (respectively 0.32.0 and 0.2.0). Even after the upgrade, I'm still having this issue on IOS when I focus an input and keyboard shows up.

image

My package.json looks like this:

"dependencies": {
    "buffer": "^4.9.0",
    "native-base": "0.5.7",
    "react": "~15.3.0",
    "react-native": "0.32.0",
    "react-native-code-push": "^1.13.5-beta",
    "react-native-fbsdk": "^0.3.0",
    "react-native-i18n": "0.0.8",
    "react-native-image-picker": "^0.21.5",
    "react-native-keyboard-aware-scroll-view": "0.2.0",
    "react-native-multiple-choice": "0.0.8",
    "react-native-swiper": "^1.4.9",
    "react-native-vector-icons": "^2.0.3",
    "react-redux": "^4.4.5",
    "redux": "^3.5.2",
    "redux-logger": "^2.6.1",
    "redux-persist": "^3.2.2",
    "redux-promise": "^0.5.3",
    "redux-thunk": "^2.1.0",
    "remote-redux-devtools": "^0.3.4",
    "rx": "^4.1.0"
  }

Am I missing something or is this a bug?

Thanks!

Cannot get it to work

I cann't get it to work properly. Here is how it looks for me:

http://i.imgur.com/nO1m1fg.gif

'use strict'

import React, {
    Component,
    AppRegistry,
    Text,
    TextInput,
    View,
    ScrollView,
} from 'react-native'
import { KeyboardAwareScrollView, } from 'react-native-keyboard-aware-scroll-view'

class KeyboardScrollTest extends Component {
    render() {
        return (
            <View style={{height:600}}>
                <View style={{flex:3}}></View>
                <View style={{flex:1}}>
                    <KeyboardAwareScrollView>
                        <TextInput style={{bordrerColor:'black',borderWidth:1,height:40}} />
                    </KeyboardAwareScrollView>
                </View>
            </View>
        )
    }
}

AppRegistry.registerComponent('KeyboardScrollTest', () => KeyboardScrollTest)

I've pushed the code https://github.com/OleksandrBezhan/react-native-keyboard-aware-scroll-view-test

View doesnot come to its original position after it moves up.

When i input text in textfield, the textfield moves up and provides user to input , but when i completed inputing text and click on done, the textinput field doesnot comes to its original place, i have enabled alwaysBounceVertical={true} and scrollEnabled={false}. what had happened now? i think the view should comes to its original place after text input task is finished.

New Bug in ancestor_check branch

I use ancestor_check branch and modify the RN core file follow Adds the ability to use UIManager to check if a node is an ancestor , they seems working correct about Text input field component + Redux but when just click a input field in a web page (WebView) it occurred a error like below. my environment is RN0.31 and NativeBase 0.52, NativeBase use the react-native-keyboard-aware-scroll-view as him Content component. Any one can give me some suggest?

Argument 0 (NSNumber) of RCTUIManager.viewIsDescendantOf must not be null

wechatimg6

0.26 breaking change

Looks like RN 0.26 broke this plugin, the error I get is
"Super expression must either be null or a function, not undefined"

the code in android made the app die

if(Platform.OS === 'android') {

     try {
       this.scrollToFocusedInputWithNodeHandle(currentlyFocusedField)
     } catch (e) {

     }
  } else {
    UIManager.viewIsDescendantOf(
        currentlyFocusedField,
        this.getScrollResponder().getInnerViewNode(),
        (isAncestor) => {
          if (isAncestor) {
            // Check if the TextInput will be hidden by the keyboard
            UIManager.measureInWindow(currentlyFocusedField, (x, y, width, height) => {
              if (y + height > frames.endCoordinates.screenY) {
                this.scrollToFocusedInputWithNodeHandle(currentlyFocusedField)
              }
            })
          }
        }
    )
  }

Some props of KeyboardAwareListView are not required

KeyboardAwareListView inherited propTypes from ListView. Some of the props there are listed with .isRequired but do have default props set. As KeyboardAwareListView doesn't have default props, this would trigger some warnings in development mode.

Don't break API on minor versions

Before I complain a bit. Thanks for this. It solved a need that I had. Now, on to my mild rant.

I reloaded my node_modules with my dependency set at "react-native-keyboard-aware-scroll-view": "~0.1.0", to allow non-breaking changes (according to semantic versioning).

This upgraded me from 0.1.0 to 0.1.2. Now KASV requires React Native 0.27. This is a breaking change and should be reserved for a 0.2.0 release. For now, I'll just fix my package.json but you should try to avoid this situation in order to be producing a quality reusable component.

reactNode is null

When following the instructions listed in the readme, on react-native 0.24, on iOS. I get the following message

image

I've traced it down to

_onTextFieldFocused(event, reactNode) {
   this.refs.scroll.scrollToFocusedInput(event, reactNode)
}

When I step into this function, after onFocus={this._onTextFieldFocused} is triggered. event is a ReactSyntheticEvent and reactNode is not defined. It seems that scrollToFocusedInput fails because no reactNode is present.

Any tips?

After input emoji in iOS, keyboard disappeared, but has a little bit of issue.

Input emoji:
emoji8

Input text is ok:
emoji9

looking at the gifs above, keyboard is disappeared, but the UI doesn't recover to beginning(Input component doesn't drop to bottom).

source code is like this:

 <KeyboardAwareScrollView
        style={styles.container}
        scrollEnabled={false}
        keyboardShouldPersistTaps={true}
        contentInset={{ bottom: PlatformSize({ios: 1, android: 0}) }}
      >
        <ListView
          ref={ref => this.listView = ref}
          style={[styles.ListView, { height: this.listHeight }]}
          enableEmptySections={true}
          dataSource={dataSource}
          renderRow={this.renderRow}
          onContentSizeChange={() => { this.setListViewPosition() }} />
          <View style={styles.footerContainer}>
            <TextInput
              style={styles.inputText}
              value={this.state.commentText}
              autoCapitalize={'none'}
              placeholder={'Enter'}
              multiline={true}
              autoCorrect={false}
              keyboardType='default'
              onChangeText={this._handleTextChange} />
            <SubmitButton
              isPosting={this.props.isPosting}
              onPress={this._onSubmit} />
          </View>
      </KeyboardAwareScrollView>

Argument 0 (NSNumber) of RCTUIManager.measureLayout must not be null

Getting this error. Any ideas?

image

Src

class ScrollableLoginScreen extends React.Component {
  _scrollToInput (event, reactNode) {
  // Add a 'scroll' ref to your ScrollView
    this.refs.scroll.scrollToFocusedInput(event, reactNode)
  }

  render() {
    return (
      <KeyboardAwareScrollView ref='scroll'>
        <LoginScreen {...this.props} scrollToInput={this._scrollToInput.bind(this)} />
      </KeyboardAwareScrollView>
    )
  }
}
class LoginScreen extends React.Component {
  render() {
    const {fields, handleSubmit, submitting, error, scrollToInput, ...props} = this.props
    return (
      <View style={styles.screen}>
        <StatusBar hidden={false} />
        <View style={styles.modal}>
          <IconTextInput ref='my-input' iconName="envelope-o" placeholder='Email' style={styles.input} {...fields.email} onFocus={scrollToInput} />
          <IconTextInput iconName="lock" placeholder='Password' style={styles.input} {...fields.password} onFocus={scrollToInput} />
          <Button style={theme.BUTTON} styleDisabled={theme.BUTTON_DISABLED} containerStyle={styles.loginButton} 
            disabled={submitting} onPress={handleSubmit}>LOGIN</Button>
          {submitting && <Spinner />}
          {(!submitting && error) && <Text style={theme.TEXT_ERROR}>{error}</Text>}
        </View>
      </View>
    )
  }
}

Position not quite right

It looks like the keyboard isn't positioned quite right - it overlaps the text input.

screen shot 2016-07-18 at 12 32 21

I think it changed after upgrading to RN 0.29

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.