├── .gitignore
├── .DS_Store
├── img
└── demo.gif
├── package.json
├── LICENSE
├── README.md
└── KeyboardDodgingView.js
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | .npm-debug.log
3 |
--------------------------------------------------------------------------------
/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/shaddeen/react-native-keyboard-dodging-view/HEAD/.DS_Store
--------------------------------------------------------------------------------
/img/demo.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/shaddeen/react-native-keyboard-dodging-view/HEAD/img/demo.gif
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "react-native-keyboard-dodging-view",
3 | "version": "1.0.0",
4 | "description": "A view that shifts up when the keyboard is presented",
5 | "main": "KeyboardDodgingView.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1"
8 | },
9 | "repository": {
10 | "type": "git",
11 | "url": "https://github.com/shaddeen/react-native-keyboard-dodging-view.git"
12 | },
13 | "keywords": [
14 | "react-native",
15 | "keyboard",
16 | "view",
17 | "component"
18 | ],
19 | "author": "Shad Deen",
20 | "license": "MIT",
21 | "bugs": {
22 | "url": "https://github.com/ide/react-native-keyboard-dodging-view/issues"
23 | },
24 | "homepage": "https://github.com/shaddeen/react-native-keyboard-dodging-view"
25 | }
26 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2016 Shad
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # react-native-keyboard-dodging-view
2 |
3 | A react-native component for iOS that shifts the view up when the keyboard is presented. There are a few examples of this available including [KeyboardAvoidingView](https://facebook.github.io/react-native/releases/next/docs/keyboardavoidingview.html) but I've run into issues with this, particularly when using multiple fields. This solution aims to tackle this problem.
4 |
5 | 
6 |
7 | ##Setup
8 |
9 | `npm install --save react-native-keyboard-dodging-view`
10 |
11 | ##Props
12 |
13 | | Prop | Type | |
14 | |---|---|---|
15 | | `verticalOffset` | `number` | (Optional) Additional vertical offset |
16 |
17 | ##Usage
18 |
19 | Import:
20 | ```
21 | import KeyboardDodgingView from 'KeyboardDodgingView`
22 | ```
23 | Example:
24 | ```
25 | class Example extends Component {
26 | render() {
27 | return (
28 |
29 |
30 | this.refs.secondField.focus()} style={{height: 50, margin: 10, marginBottom: 0, backgroundColor: 'white'}} />
31 |
32 |
33 |
34 | );
35 | }
36 | }
37 | ```
38 |
39 | ##Features
40 | - Dynamically calculates the height required to shift contents up
41 | - Accounts for changes in keyboard size
42 | - Handles multiple textfield selection
43 |
44 | ##Outstanding issues
45 | - Slight jump when switching text fields via the keyboard return key on iOS 8
46 | - Measurements are off when content is vertically aligned by a container view (with `justifyContent: 'center'`)
47 |
--------------------------------------------------------------------------------
/KeyboardDodgingView.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @providesModule KeyboardDodgingView
3 | * https://github.com/shaddeen/react-native-keyboard-dodging-view
4 | * @flow
5 | */
6 |
7 | import React from 'react';
8 |
9 | import {
10 | View,
11 | Keyboard,
12 | LayoutAnimation,
13 | Platform
14 | } from 'react-native';
15 |
16 | class KeyboardDodgingView extends React.Component {
17 | static propTypes = {
18 | ...View.propTypes,
19 | verticalOffset: React.PropTypes.number
20 | };
21 |
22 | static defaultProps = {
23 | verticalOffset: 0
24 | };
25 |
26 | constructor () {
27 | super();
28 |
29 | this.state = {
30 | top: 0
31 | };
32 | }
33 |
34 | componentWillMount () {
35 | if (Platform.OS == 'ios') {
36 | this._subscriptions = [
37 | Keyboard.addListener('keyboardWillChangeFrame', (event) => this.onKeyboardChange(event)),
38 | Keyboard.addListener('keyboardWillShow', (event) => this.onKeyboardWillShow(event)),
39 | Keyboard.addListener('keyboardWillHide', (event) => this.onKeyboardWillHide(event))
40 | ];
41 | }
42 | }
43 |
44 | componentWillUnmount () {
45 | Platform.OS == 'ios' && this._subscriptions.forEach((subscription) => subscription.remove());
46 | }
47 |
48 | onKeyboardWillShow (event) {
49 | this._keyboardVisible = true;
50 | this.onKeyboardChange(event);
51 | }
52 |
53 | onKeyboardWillHide (event) {
54 | this._keyboardVisible = false;
55 | this._keyboardHeight = 0;
56 | this.onKeyboardChange(event);
57 | }
58 |
59 | onKeyboardChange (event) {
60 | let top = 0;
61 |
62 | if (!event || !this._frame) {
63 | this.setState({top});
64 | return;
65 | }
66 |
67 | const {duration, easing, startCoordinates, endCoordinates} = event;
68 | const viewHeight = this._frame.height;
69 | const viewTopOffset = this._frame.y;
70 |
71 | if (this._keyboardHeight === endCoordinates.height) {
72 | return;
73 | }
74 |
75 | if (this._keyboardHeight !== endCoordinates.height || startCoordinates.screenY > endCoordinates.screenY) {
76 | if (endCoordinates.screenY - viewHeight < viewTopOffset) {
77 | top = endCoordinates.screenY - viewTopOffset - viewHeight - this.props.verticalOffset;
78 | }
79 | }
80 |
81 | this.animateLayout(duration, easing);
82 | this.setState({top});
83 | if (this._keyboardVisible) {
84 | this._keyboardHeight = endCoordinates.height;
85 | }
86 | }
87 |
88 | animateLayout (duration = 250, easing = 'keyboard') {
89 | LayoutAnimation.configureNext({
90 | duration: duration,
91 | update: {
92 | duration: duration,
93 | type: LayoutAnimation.Types[easing]
94 | }
95 | });
96 | }
97 |
98 | onLayout (event) {
99 | if (event && event.nativeEvent.layout !== this._frame) {
100 | this._frame = event.nativeEvent.layout;
101 | this.props.onLayout && this.props.onLayout(event);
102 | }
103 | }
104 |
105 | render () {
106 | const {style, ...props} = this.props;
107 | return (
108 | this.onLayout(event)} />
109 | );
110 | }
111 | }
112 |
113 | module.exports = KeyboardDodgingView;
114 |
--------------------------------------------------------------------------------