Tech Blog - mixross

react-native-paperのDialog(Modal)で表示しているとキーボードが消えない

このエントリーをはてなブックマークに追加
LINE

環境

react-native 0.63.1
react-native-paper 3.10.1

ライブラリの追加

$ yarn add react-native-paper

アイコンを使用するならreact-native-vector-iconsが必要になるので一緒にインストールする。
この記事 を参考。

Dialogを使ったサンプル

ReactNativeインストール直後のApp.jsをいじってDialogを表示するだけの画面を作成

App.js
import * as React from 'react'
import {
  SafeAreaView,
} from 'react-native'
import {
  Provider as PaperProvider,
  Button,
  Portal,
  Dialog,
  Paragraph,
  TextInput,
} from 'react-native-paper'

const App: () => React$Node = () => {

  const [visible, setVisible] = React.useState(false)

  const closeDialog = () => {
    setVisible(false)
  }

  return (
    <PaperProvider>
      <SafeAreaView>
        <Button onPress={() => setVisible(true)}>
          Open
        </Button>
        <Portal>
          <Dialog
            visible={visible}
            dismissable={true}
            onDismiss={closeDialog}
          >
            <Dialog.Title>
              タイトル
            </Dialog.Title>
            <Dialog.Content>
              <Paragraph>
                テキスト入力
              </Paragraph>
              <TextInput
                mode={'outlined'}
              />
            </Dialog.Content>
            <Dialog.Actions>
              <Button onPress={closeDialog}>OK</Button>
            </Dialog.Actions>
          </Dialog>
        </Portal>
      </SafeAreaView>
    </PaperProvider>
  )
}

export default App

起動直後

screenshot1

OPENをタップしてダイアログが表示される

screenshot2

TextInputをタップしてキーボードを表示

screenshot3

このあと、ダイアログのどこをタップしてもキーボードが閉じない。
ダイアログのバックドロップ(画面とダイアログの間にあるグレーの板)をタップすれば閉じるが、当然ダイアログも閉じてしまう。

ダイアログを残したままキーボードが閉じるように修正

いくら調べても原因究明できなかったため、Dialogの各パーツのタップイベント処理(onPressが無いものはTouchableWithoutFeedbackでラップ)にてキーボードを閉じるようにと強引に修正。

App.js
import * as React from 'react'
import {
  SafeAreaView,
  TouchableWithoutFeedback,  Keyboard,} from 'react-native'
import {
  Provider as PaperProvider,
  Button,
  Portal,
  Dialog,
  Paragraph,
  TextInput,
} from 'react-native-paper'

const App: () => React$Node = () => {

  const [visible, setVisible] = React.useState(false)

  const closeDialog = () => {
    setVisible(false)
  }

  const dismissKeyboard = () => {    Keyboard.dismiss()  }
  return (
    <PaperProvider>
      <SafeAreaView>
        <Button onPress={() => setVisible(true)}>
          Open
        </Button>
        <Portal>
          <Dialog
            visible={visible}
            dismissable={true}
            onDismiss={closeDialog}
          >
            <Dialog.Title onPress={dismissKeyboard}>              タイトル
            </Dialog.Title>
            <TouchableWithoutFeedback onPress={dismissKeyboard}>              <Dialog.Content>
                <Paragraph>
                  テキスト入力
                </Paragraph>
                <TextInput
                  mode={'outlined'}
                />
              </Dialog.Content>
            </TouchableWithoutFeedback>            <TouchableWithoutFeedback onPress={dismissKeyboard}>              <Dialog.Actions>
                <Button onPress={closeDialog}>OK</Button>
              </Dialog.Actions>
            </TouchableWithoutFeedback>          </Dialog>
        </Portal>
      </SafeAreaView>
    </PaperProvider>
  )
}

export default App
RSS