diff --git a/README.md b/README.md index 25d3cce..3a29774 100644 --- a/README.md +++ b/README.md @@ -95,8 +95,9 @@ All the `ScrollView`/`ListView` props will be passed. |----------|----------|-----------------| | `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. | -| `enableAutoAutomaticScroll` | `boolean` | When focus in TextInput will scroll the position, default is enabled. | -| `extraHeight` | `number` | Adds an extra offset | +| `enableAutoAutomaticScroll` | `boolean` | When focus in `TextInput` will scroll the position, default is enabled. | +| `extraHeight` | `number` | Adds an extra offset when focusing the `TextInput`s. | +| `extraScrollHeight` | `number` | Adds an extra offset to the keyboard. Useful if you want to stick elements above the keyboard. | ## License diff --git a/lib/KeyboardAwareMixin.js b/lib/KeyboardAwareMixin.js index 9289a2e..32c3ba0 100644 --- a/lib/KeyboardAwareMixin.js +++ b/lib/KeyboardAwareMixin.js @@ -4,21 +4,23 @@ import { PropTypes } from 'react' import ReactNative, { TextInput, Keyboard, UIManager } from 'react-native' import TimerMixin from 'react-timer-mixin' -const _KAM_DEFAULT_TAB_BAR_HEIGHT = 49 -const _KAM_KEYBOARD_OPENING_TIME = 250 -const _KAM_EXTRA_HEIGHT = 75 +const _KAM_DEFAULT_TAB_BAR_HEIGHT: number = 49 +const _KAM_KEYBOARD_OPENING_TIME: number = 250 +const _KAM_EXTRA_HEIGHT: number = 75 const KeyboardAwareMixin = { mixins: [TimerMixin], propTypes: { enableAutoAutomaticScroll: PropTypes.bool, extraHeight: PropTypes.number, + extraScrollHeight: PropTypes.number, }, getDefaultProps: function () { return { - enableAutoAutomaticScroll: true, - extraHeight: _KAM_EXTRA_HEIGHT, + enableAutoAutomaticScroll: true, + extraHeight: _KAM_EXTRA_HEIGHT, + extraScrollHeight: 0, } }, @@ -42,17 +44,17 @@ const KeyboardAwareMixin = { // Keyboard actions updateKeyboardSpace: function (frames: Object) { - const keyboardSpace = (this.props.viewIsInsideTabBar) ? frames.endCoordinates.height - _KAM_DEFAULT_TAB_BAR_HEIGHT : frames.endCoordinates.height - this.setState({ - keyboardSpace: keyboardSpace, - }) + let keyboardSpace: number = frames.endCoordinates.height + this.props.extraScrollHeight + if (this.props.viewIsInsideTabBar) { + keyboardSpace -= _KAM_DEFAULT_TAB_BAR_HEIGHT + } + this.setState({keyboardSpace}) // Automatically scroll to focused TextInput if (this.props.enableAutoAutomaticScroll) { const currentlyFocusedField = TextInput.State.currentlyFocusedField() if (!currentlyFocusedField) { return } - UIManager.viewIsDescendantOf( currentlyFocusedField, this.getScrollResponder().getInnerViewNode(), @@ -60,7 +62,7 @@ const KeyboardAwareMixin = { 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) { + if (y + height > frames.endCoordinates.screenY - this.props.extraScrollHeight - this.props.extraHeight) { this.scrollToFocusedInputWithNodeHandle(currentlyFocusedField) } }) @@ -68,17 +70,14 @@ const KeyboardAwareMixin = { } ) } - if (!this.resetCoords) { this.defaultResetScrollToCoords = this.position } }, resetKeyboardSpace: function () { - const keyboardSpace = (this.props.viewIsInsideTabBar) ? _KAM_DEFAULT_TAB_BAR_HEIGHT : 0 - this.setState({ - keyboardSpace: keyboardSpace, - }) + const keyboardSpace: number = (this.props.viewIsInsideTabBar) ? _KAM_DEFAULT_TAB_BAR_HEIGHT : 0 + this.setState({keyboardSpace}) // Reset scroll position after keyboard dismissal if (this.resetCoords) { this.scrollToPosition(this.resetCoords.x, this.resetCoords.y, true) @@ -117,7 +116,7 @@ const KeyboardAwareMixin = { scrollToFocusedInputWithNodeHandle: function (nodeID: number, extraHeight: number = this.props.extraHeight) { const reactNode = ReactNative.findNodeHandle(nodeID) - this.scrollToFocusedInput(reactNode, extraHeight) + this.scrollToFocusedInput(reactNode, extraHeight + this.props.extraScrollHeight) }, position: {x: 0, y: 0},