import { useEffect, useRef } from 'react'; import { Animated, Keyboard, Platform } from 'react-native'; function getInitialKeyboardHeight() { if (Platform.OS !== 'ios') { return 0; } /** * React Native 0.68.0 버전에는 `metrics()`가 존재하지 않아 분기 처리 */ // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore if (typeof Keyboard?.metrics === 'function') { // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore return Keyboard.metrics()?.height ?? 0; } else { return 0; } } /** * @category Hooks * @name useKeyboardAnimatedHeight * @description * 키보드가 나타나거나 사라질 때, 키보드의 높이의 변화를 애니메이션 가능한 값(`Animated.Value`)으로 반환하는 Hook이에요. 키보드가 올라오거나 내려갈 때 키보드 높이에 맞춰 UI 요소를 부드럽게 변화시킬 수 있어요. * * 이 Hook은 주로 iOS에서 사용해요. Android에서는 키보드 높이 변경을 감지하지 않고, 항상 초기값이 `0`인 `Animated.Value`를 반환해요. 즉, Android 환경에서는 애니메이션이 적용되지 않아요. * * @returns {Animated.Value} - 키보드의 높이를 나타내는 애니메이션 값이에요. * @example * ```typescript * const keyboardHeight = useKeyboardAnimatedHeight(); * * * {children} * * ``` */ export function useKeyboardAnimatedHeight(): Animated.Value { const keyboardHeight = useRef(new Animated.Value(getInitialKeyboardHeight())).current; useEffect(() => { if (Platform.OS === 'ios') { const willShowSubscription = Keyboard.addListener('keyboardWillShow', (event) => { const height = event.endCoordinates.height; Animated.spring(keyboardHeight, { toValue: height, useNativeDriver: true, ...spring.quick, }).start(); }); const willHideSubscription = Keyboard.addListener('keyboardWillHide', () => { Animated.spring(keyboardHeight, { toValue: 0, useNativeDriver: true, ...spring.quick, }).start(); }); return () => { willShowSubscription.remove(); willHideSubscription.remove(); }; } else { return; } }, [keyboardHeight]); return keyboardHeight; } const spring = { quick: { stiffness: 800, damping: 55, mass: 1, }, };