React Native Make View "Hug" the Top of the Keyboard

Custom hook:

import { useRef, useEffect } from 'react';
import { Animated, Keyboard, KeyboardEvent } from 'react-native';

export const useKeyboardHeight = () => {
  const keyboardHeight = useRef(new Animated.Value(0)).current;

  useEffect(() => {
    const keyboardWillShow = (e: KeyboardEvent) => {
      Animated.timing(keyboardHeight, {
        duration: e.duration,
        toValue: e.endCoordinates.height,
        useNativeDriver: true,
      }).start();
    };

    const keyboardWillHide = (e: KeyboardEvent) => {
      Animated.timing(keyboardHeight, {
        duration: e.duration,
        toValue: 0,
        useNativeDriver: true,
      }).start();
    };

    const keyboardWillShowSub = Keyboard.addListener(
      'keyboardWillShow',
      keyboardWillShow
    );
    const keyboardWillHideSub = Keyboard.addListener(
      'keyboardWillHide',
      keyboardWillHide
    );

    return () => {
      keyboardWillHideSub.remove();
      keyboardWillShowSub.remove();
    };
  }, [keyboardHeight]);

  return keyboardHeight;
};

Using Functional Component. This works for both iOS and Android

useEffect(() => {
const keyboardVisibleListener = Keyboard.addListener(
  Platform.OS === "ios" ? "keyboardWillShow" : "keyboardDidShow",
  handleKeyboardVisible
);
const keyboardHiddenListener = Keyboard.addListener(
  Platform.OS === "ios" ? "keyboardWillHide" : "keyboardDidHide",
  handleKeyboardHidden
);

return () => {
  keyboardHiddenListener.remove();
  keyboardVisibleListener.remove();
};}, []);


const handleKeyboardVisible = (event) => {
Animated.timing(paddingInput, {
  duration: event.duration,
  toValue: 60,
  useNativeDriver: false,
});};

 const handleKeyboardHidden = (event: any) => {
Animated.timing(paddingInput, {
  duration: event.duration,
  toValue: 0,
  useNativeDriver: false,
});};

Few days ago I have the same problem (although I have a complex view with TextInput as a child) and wanted not only the TextInput to be focused but the whole view to be "attached" to the keyboard. What's finally is working for me is the following code:

constructor(props) {
    super(props);
    this.paddingInput = new Animated.Value(0);
}

componentWillMount() {
    this.keyboardWillShowSub = Keyboard.addListener('keyboardWillShow', this.keyboardWillShow);
    this.keyboardWillHideSub = Keyboard.addListener('keyboardWillHide', this.keyboardWillHide);
}

componentWillUnmount() {
    this.keyboardWillShowSub.remove();
    this.keyboardWillHideSub.remove();
}

keyboardWillShow = (event) => {
    Animated.timing(this.paddingInput, {
        duration: event.duration,
        toValue: 60,
    }).start();
};

keyboardWillHide = (event) => {
    Animated.timing(this.paddingInput, {
        duration: event.duration,
        toValue: 0,
    }).start();
};

render() {
        return (
            <KeyboardAvoidingView behavior='padding' style={{ flex: 1 }}>
                [...]
                <Animated.View style={{ marginBottom: this.paddingInput }}>
                    <TextTranslateInput />
                </Animated.View>
            </KeyboardAvoidingView>
        );
    }

where [..] you have other views.


@jazzdle example works great! Thank you for that! Just one addition - in keyboardWillShow method, one can add event.endCoordinates.height so paddingBottom is exact height as keyboard.

    keyboardWillShow = (event) => {
    Animated.timing(this.paddingInput, {
        duration: event.duration,
        toValue: event.endCoordinates.height,
    }).start();
}