ぽっちぽちにしてやんよ

技術ネタとかアプリに関する話とか

React Nativeで画面を作ってるときにキーボードでボタンが隠れて困るときに使えるKeyboardAvoidingViewが良いという話

こんにちは,ぽちです.

何かとReact Nativeでアプリを作っているとフォーム的なやつよく作りますよね. 上にテキストフォームを置いて,下に決定ボタンを置くデザインなどが非常に良くあるデザインですが,単純に実装してしまうと、下の決定ボタンがキーボードによって隠れてしまって使い勝手が良くない…ということ,良くありますよね. 上部に長文を書くTextInputを,下部に決定ボタンを置いたものを例に挙げると,

f:id:poChi:20170607132211g:plain

このような形で決定ボタン(Tap Hereと書いてある領域)がテキスト入力時に出てきたキーボードによって隠れてしまいます.

そんな時にReact Nativeではこの現象を回避するためのコンポーネントが用意されてたりします. それがKeyboardAvoidingViewです.

このKeyboardAvoidingViewですが,設定するbehaviorプロパティが直感的には分かりにくく「どれを使えばいいんだ!」となりがちです.それぞれbehaviorに設定した値によって動きがどう変わるのかを見ていきます.

(コードサンプルだけ欲しい方は KeyboardAvoidingViewSample · GitHub をどうぞ)

まず,KeyboardAvoidingViewを使うのでimportします.

import { KeyboardAvoidingView } from 'react-native';

KeyboardAvoidingViewを使わない場合のrender()で返すJSXのコードは,

<View style={{flex: 1}}>
  <TextInput style={{flex: 10}} />
  <TouchableOpacity style={{flex: 1, (略)}}>
    <Text>Tap Here</Text>
  </TouchableOpacity>
</View>

のような形になっています.

よく全体を<View>で囲ったりしますが(単一のコンポーネントを返さないといけないため),その直下に<KeyboardAvoidingView>で囲みます.

<View style={{flex: 1}}>
  <KeyboardAvoidingView behavior={this.state.behavior}>
    <TextInput style={{flex: 10}} />
    <TouchableOpacity style={{flex: 1, (略)}}>
      <Text>Tap Here</Text>
    </TouchableOpacity>
  <KeyboardAvoidingView>
</View>

そこで,問題となるのがbehaviorプロパティです. このプロパティには以下の文字列値を取ります.

  • padding
  • height
  • position

それぞれ図を交えて説明します.

behavior=‘padding’

大体paddingを指定しておけばうまく行くケースが多いです. 動作的には,画面を構成する要素(今回だとTextInputとかTouchableOpacityとかの部分)がflexプロパティで構成されていれば,キーボードで狭くなった領域を100%として調整してくれます.

f:id:poChi:20170607132245g:plain

そしてキーボードを閉じると,キーボードを開く前と同じ状態に戻ってきます.

behavior=‘height’

使い道がよくわからないのですが,大体の動作はpaddingを指定した際と同等の動きをします. 違うのは,キーボードを閉じたときに,キーボードを開いて狭まった領域がそのまま維持されるということです.(キーボードがあった領域がそのまま空く)

f:id:poChi:20170607132312g:plain

behavior=‘position’

positionを指定した場合は,<KeyboardAvoidingView>のプロパティにcontentContainerStyleを指定します.(positionを指定したときだけ有効なプロパティです) positionを指定し,キーボードが現れたときに<View>コンポーネントで囲まれるため,{flex: 1}heightを指定しないと要素がグシャっとなってしまうことがよく有ります. キーボードを閉じるとまた元の状態に戻ります. 細かく指定したい場合はpositionを使うと良いのではないでしょうか.

f:id:poChi:20170607132342g:plain

まとめ

キーボードでUI要素が隠れて困る場合はKeyboardAvoidingViewコンポーネントを活用しよう!

動作を確認するために使ったコードは KeyboardAvoidingViewSample · GitHub に置いておくので,いじったりして動作を色々見てもらったら分かりやすいと思います.