-
-
Save larkintuckerllc/15644c314207df00c212ecb14b981439 to your computer and use it in GitHub Desktop.
| import { PropTypes } from 'prop-types'; | |
| import React, { Component } from 'react'; | |
| import { Animated, Dimensions, Keyboard, StyleSheet, TextInput, UIManager } from 'react-native'; | |
| const { State: TextInputState } = TextInput; | |
| export default class KeyboardShift extends Component { | |
| state = { | |
| shift: new Animated.Value(0), | |
| }; | |
| componentWillMount() { | |
| this.keyboardDidShowSub = Keyboard.addListener('keyboardDidShow', this.handleKeyboardDidShow); | |
| this.keyboardDidHideSub = Keyboard.addListener('keyboardDidHide', this.handleKeyboardDidHide); | |
| } | |
| componentWillUnmount() { | |
| this.keyboardDidShowSub.remove(); | |
| this.keyboardDidHideSub.remove(); | |
| } | |
| render() { | |
| const { children: renderProp } = this.props; | |
| const { shift } = this.state; | |
| return ( | |
| <Animated.View style={[styles.container, { transform: [{translateY: shift}] }]}> | |
| {renderProp()} | |
| </Animated.View> | |
| ); | |
| } | |
| handleKeyboardDidShow = (event) => { | |
| const { height: windowHeight } = Dimensions.get('window'); | |
| const keyboardHeight = event.endCoordinates.height; | |
| const currentlyFocusedField = TextInputState.currentlyFocusedField(); | |
| UIManager.measure(currentlyFocusedField, (originX, originY, width, height, pageX, pageY) => { | |
| const fieldHeight = height; | |
| const fieldTop = pageY; | |
| const gap = (windowHeight - keyboardHeight) - (fieldTop + fieldHeight); | |
| if (gap >= 0) { | |
| return; | |
| } | |
| Animated.timing( | |
| this.state.shift, | |
| { | |
| toValue: gap, | |
| duration: 1000, | |
| useNativeDriver: true, | |
| } | |
| ).start(); | |
| }); | |
| } | |
| handleKeyboardDidHide = () => { | |
| Animated.timing( | |
| this.state.shift, | |
| { | |
| toValue: 0, | |
| duration: 1000, | |
| useNativeDriver: true, | |
| } | |
| ).start(); | |
| } | |
| } | |
| const styles = StyleSheet.create({ | |
| container: { | |
| height: '100%', | |
| left: 0, | |
| position: 'absolute', | |
| top: 0, | |
| width: '100%' | |
| } | |
| }); | |
| KeyboardShift.propTypes = { | |
| children: PropTypes.func.isRequired, | |
| }; |
hi @LyricL-Gitster thank you so much for the Hooks & TS code snippet!
The code works but there is an annoying error message every time i try to open a TextInput:
currentlyFocusedField is deprecated and will be removed in a future release. Use currentlyFocusedInput
I understand that currentlyFocusedField would return the ID of the focused TextInput. However, currentlyFocusedInput apparently returns the ref of the currently focused text field, so I can't simply replace currentlyFocusedField with currentlyFocusedInput. Is there any way for me to get the ID of the field using currentlyFocusedInput?
I read online for solutions regarding this but there seems to be none that is clean. The solutions I read involves modifying node-modules which is a very hacky way and I would like to avoid such methods.
@wilbertaristo you can replace it by grabbing the native id from the currentlyFocusedInput object:
// replace currentlyFocusedField with this:
const { _nativeTag } = TextInputState.currentlyFocusedInput();@jforaker that works! thank you so much :) btw to prevent TypeScript from giving me errors I modified the above into:
const { _nativeTag } = (TextInputState as any).currentlyFocusedInput();@wilbertaristo can u please post here updated typescript class
cause of UIManager.measure also depricated.
Thanks for this btw. I've updated it for using with hooks and TS if anyone needs: