Skip to content

Instantly share code, notes, and snippets.

@sloanwolf
Forked from tahaziadeh/KeyboardHandler.js
Last active October 30, 2016 05:47
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sloanwolf/bcface99e86c36607aeb8e71b2abe105 to your computer and use it in GitHub Desktop.
Save sloanwolf/bcface99e86c36607aeb8e71b2abe105 to your computer and use it in GitHub Desktop.
Keyboard spacing solution for react-native based on the stackoverflow answer http://stackoverflow.com/a/33585501/1783214
// Based on dbasedow/KeyboardHandler.js
/**
* Based on http://stackoverflow.com/a/33585501/1783214
*
* Handle resizing enclosed View and scrolling to input
* Usage:
* <KeyboardHandler ref='kh' offset={50} >
* <View>
* ...
* <TextInput ref='username'
* onFocus={()=>this.refs.kh.inputFocused(this,'username')}/>
* ...
* </View>
* </KeyboardHandler>
*
* offset is optional and defaults to 34
* Any other specified props will be passed on to ScrollView
*/
'use strict';
import React, { Component } from 'react';
import ReactNative, {
ScrollView,
View,
Keyboard,
Platform,
TextInput,
TouchableWithoutFeedback,
// DeviceEventEmitter,
} from 'react-native';
var DismissKeyboard = require('dismissKeyboard');
class KeyboardHandler extends Component {
constructor(props) {
super(props);
this.state = {keyboardSpace: 0};
this.focused = null;
this._didShowListener = null;
this._willHideListener = null;
this._listeners = null;
}
onKeyboarDidShow(frames) {
if (!frames.endCoordinates || !this.focused) {
return;
}
this.setState({keyboardSpace: frames.endCoordinates.height});
let scrollResponder = this.refs.scrollView.getScrollResponder();
scrollResponder.scrollResponderScrollNativeHandleToKeyboard(
this.focused,
this.props.offset, //additionalOffset
true
);
}
onKeyboardWillHide() {
this.setState({keyboardSpace: 0});
}
componentWillMount() {
let _this=this;
const updateListener = Platform.OS === 'android' ? 'keyboardDidShow' : 'keyboardWillShow';
const resetListener = Platform.OS === 'android' ? 'keyboardDidHide' : 'keyboardWillHide';
this._listeners = [
Keyboard.addListener(updateListener, this.onKeyboarDidShow.bind(this)),
Keyboard.addListener(resetListener, this.onKeyboardWillHide.bind(this))
];
//i've added the ability to overwrite the keyboardShouldPersistTaps props
//when you use this component in a page that can be reached by navigation
//you have to overwrite this props to false
//this update will fix the onBlur event bug of this component:
/* Usage:
* <KeyboardHandler ref='kh' offset={50} keyboardShouldPersistTaps={false}>
* <View>
* ...
* <TextInput ref='username'
* onFocus={()=>this.refs.kh.inputFocused(this,'username')}/>
* ...
* </View>
* </KeyboardHandler>
*/
this.scrollviewProps = {
automaticallyAdjustContentInsets: true,
keyboardShouldPersistTaps: _this.props.keyboardShouldPersistTaps || true,
scrollEventThrottle: 200,
contentContainerStyle: _this.props.contentContainerStyle,
};
// pass on any props we don't own to ScrollView
Object.keys(this.props).filter((n) => {
return n != 'children'
})
.forEach((e) => {
this.scrollviewProps[e] = this.props[e]
});
}
componentWillUnmount() {
this._listeners.forEach(listener => listener.remove());
}
render() {
return (
<ScrollView ref='scrollView' {...this.scrollviewProps}>
<TouchableWithoutFeedback onPress={ () => { DismissKeyboard(); } }>
<View style={{flex:1}}>
{this.props.children}
<View style={{ height: this.state.keyboardSpace }}/>
</View>
</TouchableWithoutFeedback>
</ScrollView>
);
}
inputFocused(_this, refName) {
this.focused = ReactNative.findNodeHandle(_this.refs[refName]);
}
scrollToFocusedInput(event, reactNode) {
this.focused = reactNode;
}
static propTypes = {
offset: React.PropTypes.number
};
static defaultProps = {
offset: 0
};
}
export default KeyboardHandler;
@sloanwolf
Copy link
Author

Forked this wrapper component again using TouchableWithoutFeedback to dismiss the keyboard when tapping outside of the child TextInputs. Child button events still work on tap. In my situation it works very well.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment