React Native: как программно открыть клавиатуру после закрытия модального окна?

Рассмотрим следующую ситуацию:

Есть страница с Input и Button для открытия модального окна.

В модальном есть другой Button, чтобы закрыть этот модальный, чтобы сфокусировать Input и показать Keyboard.

Проблема:

Сразу после нажатия другой Button, чтобы закрыть модальное окно, сфокусировать Input и показать Keyboard, происходит следующее:

  1. Модальное окно закрыто.
  2. Input имеет фокус.
  3. Но Keyboard НЕ отображается.

Это мой код:

import React, { useState, useEffect, useRef } from 'react';
import { View } from 'react-native';

import { Button, Input, Overlay } from 'react-native-elements';

const App = () => {
  const [isInputFocused, setInputFocused] = useState(false);
  const [isModalVisible, setModalVisible] = useState(false);

  const inputRef = useRef(null);

  useEffect(() => {
    isInputFocused ? inputRef.current.focus() : inputRef.current.blur();
  }, [isInputFocused]);

  const handleInputFocus = () => setInputFocused(true);
  const handleInputBlur = () => setInputFocused(false);

  const handleOpenModalButtonPress = () => setModalVisible(true);

  const handleFocusInputButtonPress = () => {
    setModalVisible(false);

    setInputFocused(true);
  };

  const handleModalBackdropPress = () => setModalVisible(false);

  return (
    <View style={{ justifyContent: 'space-around', flex: 1, padding: 25 }}>
      <Input
        ref={inputRef}
        onFocus={handleInputFocus}
        onBlur={handleInputBlur}
      />

      <Button
        title="Open Modal"
        onPress={handleOpenModalButtonPress}>
      </Button>

      <Overlay visible={isModalVisible} onBackdropPress={handleModalBackdropPress}>
        <Button title="Focus Input and Open Keyboard" onPress={handleFocusInputButtonPress} />
      </Overlay>
    </View>
  );
};

export default App;

Вы можете увидеть это вживую здесь.

Вопрос:

Можно ли открыть клавиатуру программно? Наверное, это решило бы мою проблему.

Если нет, может ли кто-нибудь объяснить, чего мне не хватает в моем текущем подходе, или предложить другое решение?

Заранее спасибо.

P.S.

  • Пакет react-native-elements используется здесь только в целях стилизации.

    Input наследует все TextInput реквизиты, Overlay - Modal и Button - TouchableWithoutFeedback реквизиты.

    Так что, я полагаю, они должны вести себя почти так же, как случайные React Native TextInput, Modal и TouchableWithoutFeedback.

  • В настоящее время я тестировал этот код только на Android.


person Marian13    schedule 11.04.2020    source источник
comment
Отвечает ли это на ваш вопрос? Показать клавиатуру программно, используя React native   -  person Cameron Little    schedule 11.04.2020
comment
Возможно, скрытие модальных конфликтов с отображаемой клавиатурой? Я видел, как это происходило при навигации между экранами. Попробуйте использовать setTimeout, чтобы добавить задержку перед фокусировкой ввода (например, задержку, равную продолжительности модального отклонения).   -  person Marek Lisik    schedule 11.04.2020
comment
@ Кэмерон Литтл, извини, но нет. Я также использую ref и focus(), как предлагается в этом ответе, но это не дает желаемого поведения.   -  person Marian13    schedule 11.04.2020
comment
@MarekLisik Я только что попытался использовать setTimeout для переноса setInputFocused(true) или inputRef.current.focus(), как вы предложили, но это тоже не помогает.   -  person Marian13    schedule 11.04.2020
comment
Я проверил вашу закуску на телефоне Android, и изменение строки 24 на setTimeout(() => setInputFocused(true), 500); помогло — вы тестируете на реальном устройстве?   -  person Marek Lisik    schedule 11.04.2020
comment
@MarekLisik Спасибо за ваши усилия. setTimeout(() => setInputFocused(true), 500); работает только первый раз. Если вы попытаетесь нажать Open Modal, а затем еще раз Focus Input and Open Keyboard, клавиатура не будет отображаться.   -  person Marian13    schedule 11.04.2020


Ответы (1)


Оказывается, есть две проблемы:

  1. Клавиатура не будет отображаться, если ввод получает фокус во время закрытия модального окна - фокус должен быть отложен до завершения анимации закрытия, например. с тайм-аутом:

setTimeout(() => setInputFocused(true), 500);

  1. Как вы указал, это устранило проблему только с первой попытки - после повторного открытия модального окна клавиатура больше не отображается. Это связано с тем, что отображение модального окна закрывает клавиатуру, но, по крайней мере, на Android, фокус ввода не сбрасывается. Повторное выделение фокуса не даст никакого эффекта, и клавиатура не появится. В этой ограниченной области исправлением будет отбрасывание фокуса вручную при отображении модального окна:
const handleOpenModalButtonPress = () => {
    setModalVisible(true);

    setInputFocused(false);
};

Возможно, есть более общее решение.

person Marek Lisik    schedule 11.04.2020