React Native でキーボードを閉じる1行のViewを追加する

キーボードの真上に「閉じる」アイコンを設置して、アイコンをタップしたらキーボードが閉じるようなコンポーネントを作成します。

まずはキーボードの高さを取得する hooks を作成します。

useKeyboardHeight

useKeyboardHeight
import { KeyboardHeight } from '../states/atoms/KeyboardHeight';
import { useEffect, useState } from 'react';
import { Keyboard } from 'react-native';
import { useRecoilState } from 'recoil';

export function useKeyboardHeight() {
  const [currentKeyboardHeight, setCurrentKeyboardHeight] = useState(0);

  const [keyboardHeight, setKeyboardHeight] = useRecoilState(KeyboardHeight);

  useEffect(() => {
    const showSubscription = Keyboard.addListener('keyboardDidShow', (e) => {
      const acquisitionKeyboardHeight = e.endCoordinates.height;
      setCurrentKeyboardHeight(acquisitionKeyboardHeight);
      if (acquisitionKeyboardHeight > keyboardHeight) {
        setKeyboardHeight(acquisitionKeyboardHeight);
      }
    });
    const hideSubscription = Keyboard.addListener('keyboardWillHide', () => {
      setCurrentKeyboardHeight(0);
    });
    return () => {
      showSubscription.remove();
      hideSubscription.remove();
    };
  }, [setCurrentKeyboardHeight]);

  return { currentKeyboardHeight };
}

キーボードの最大の高さはグローバルに設定しておく

上のhooksで取得できるのは「現在のキーボードの高さ」なので、可変です。

キーボードの最大の高さを Recoil で設定しておけば、色々と便利です。

KyeboardHeight.ts
import { atom } from 'recoil';

export const KeyboardHeight = atom<number>({
  key: 'KeyboardHeight',
  default: 0,
});

キーボードを閉じるコンポーネント

KeyboardCloseRow.tsx
import { useKeyboardHeight } from '../../hooks/useKeyboardHeight';
import { KEYBOARD_CLOSE_ROW_HEIGHT } from '../../utils/commonCssProperties';
import { MaterialIcons } from '@expo/vector-icons';
import { Keyboard, StyleSheet, View } from 'react-native';

export default function KeyboardCloseRow() {
  const { currentKeyboardHeight } = useKeyboardHeight();
  const closeKeyboard = () => {
    Keyboard.dismiss();
  };

  if (currentKeyboardHeight === 0) {
    return null;
  }

  return (
    <View style={[styles.row, { bottom: currentKeyboardHeight }]}>
      <MaterialIcons
        name="keyboard-hide"
        size={24}
        color="gray"
        onPress={closeKeyboard}
        style={styles.icon}
      />
    </View>
  );
}

const styles = StyleSheet.create({
  row: {
    position: 'absolute',
    height: KEYBOARD_CLOSE_ROW_HEIGHT,
    width: '100%',
    backgroundColor: 'rgba(211,211,211, 0.4)',
    flexDirection: 'row',
    alignItems: 'center',
    justifyContent: 'flex-end',
    left: 0,
    right: 0,
  },
  icon: {
    marginRight: 16,
  },
});

上のコンポーネントを使えば、アイコンタップでキーボードを閉じるようなコンポーネントになります。