React NativeでInput要素の入力後に画面を塞ぐキーボードを隠す
スマホアプリにおいて、インプット要素でソフトウェアキーボードにより要素が隠れてしまうことがあります。 スマホにおいて、キーボードは画面の3分の1から2分の1を占領するため、画面に表示できる要素が少なくなります。
Androidでは戻るボタンがハードキーで用意されている、またはホームボタンの横にあることが多いのでキーボードを簡単にしまえます。
しかし、iOSでは戻るボタンが無いのでキーボードをしまえずに困る場合があります。
この現象を回避するために以下のような方法が考えられます。
- 入力後にインプット要素以外をタップするとキーボードが隠れる
- KeybordAvoidingViewを使って、表示したい要素をキーボードを避けて上に移動させる
今回は、「入力後にインプット以外をタップするとキーボードが隠れる」実装を紹介します。
KeyboardAvoidingView
を使った実装については以前にblogで紹介していますので、参考にご活用ください。
React NativeでKeyboardAvoidingViewが意図通りに動かない場合
結論を先に言うと
TouchableWithoutFeedback
を利用して、インプット要素以外をタップした際にKeyboard.dismiss()
を実行します。
インプット要素を含む画面内のなるべく大きい範囲をTouchableWithoutFeedback
で囲みます。その上で、onPress
にキーボードを閉じる処理Keyboard.dismiss()
を設定します。
概要
- TouchableWithoutFeedback
- Keyboard.dismiss()
TouchableWithoutFeedback
ドキュメント
https://facebook.github.io/react-native/docs/touchablewithoutfeedback
React Nativeの標準コンポーネントです。タップ時に任意の処理を実行できます。
他のTouchable〜コンポーネントとの違いは、タップ時の視覚的なフィードバックが無いことです。うんともすんとも言わないです。
ですので、このようなフォーカスが外れるといったようなキャンセル処理に向いているとも言えます。
通常のボタンやリンクなどでは使わないほうがいいです。
インポート
以下のようにインポートして使います。通常はViewやTextもありますのでその場合は一緒に指定しましょう。
import { TouchableWithoutFeedback } from 'react-native';
実装
インプット要素を含む形で親コンポーネントにします。このコンポーネントをタップした際にonPressが実行されます。 今回の要件であれば、なるべく画面全体が含まれるようにします。
<TouchableWithoutFeedback
onPress={() => {
// 実行したい処理
}}>
<View>
<Input>
<Input>
</View>
</TouchableWithoutFeedback>
TouchableWithoutFeedbackの子要素は単一コンポーネントのみ受け付けます。並列に2つ以上の子要素をもたせるとエラーになるので注意しましょう。 上記のようにViewで囲んでしまえば大丈夫です。
Keyboard.dismiss()
ドキュメント
https://facebook.github.io/react-native/docs/keyboard
端末のキーボードに関わるイベントを管理するモジュールです。詳細は上記のドキュメントで確認できます。 キーボードを非表示にするほかにも、表示・非表示などのイベントに関数をaddListenerできます。
インポート
こちらもreact-native からインポートします。他のコンポーネントと同様ですので一緒に指定しましょう。
import { TouchableWithoutFeedback,Keyboard } from 'react-native';
実装
今回はキーボードをしまうKeyboard.dismiss()
を利用します。
先程のTouchableWithoutFeedback
のonPress
に設定すれば良いだけです。特に引数なども必要ありません。
<TouchableWithoutFeedback
onPress={() => {
Keyboard.dismiss()
}}>
これで、Inputをタップして入力を行った後に、Input以外の場所をタップするとキーボードが隠れるようになりました。
おわりに
今回の実装は、KeyboardAvoidingViewを使うよりも簡単です。動作も直感的にわかりやすいのでシンプルになります。 ただユーザー側で一度余計なタップが必要になりますので、UI的に検討したほうがいいです。
なんとなく、「インプット以外をタップするとフォーカスが外れてキーボードが隠れる」は、ユーザーが想定できる動きに私は感じます。 ただ、実際のすべてのユーザーがそうなのかわかりません。リテラシーやスマホの使い方、経験によっても異なりますのでUIの検討の必要がありそうです。
どちらにしても、キーボードをしまえないのは困るのでインプット要素を実装する際は、できるだけこの実装を行いましょう。