Скрыть клавиатуру в react-native

Если я нажму на textinput, я хочу иметь возможность нажать где-нибудь еще, чтобы снова закрыть клавиатуру (но не клавишу возврата). Я не нашел ни малейшей информации об этом во всех учебниках и блогах, которые я читал.

этот базовый пример все еще не работает для меня с react-native 0.4.2 в симуляторе. Пока не могу попробовать на своем iPhone.

<View style={styles.container}>
    <Text style={styles.welcome}>
      Welcome to React Native!
    </Text>
    <Text style={styles.instructions}>
      To get started, edit index.ios.js
    </Text>
    <Text style={styles.instructions}>
      Press Cmd+R to reload,{'n'}
      Cmd+D or shake for dev menu
    </Text>
    <TextInput
      style={{height: 40, borderColor: 'gray', borderWidth: 1}}
      onEndEditing={this.clearFocus}
    />
  </View>

19 ответов


проблема с клавиатурой не увольняя становится более серьезным, если у вас есть keyboardType='numeric', так как нет никакого способа отклонить его.

замена View на ScrollView не является правильным решением, как если бы у вас было несколько textInputили buttons, нажав на них, пока клавиатура вверх будет только уволить клавиатуру.

правильный способ-инкапсулировать представление с помощью TouchableWithoutFeedback, а вызов Keyboard.dismiss()

EDIT: теперь вы можете использовать ScrollView С keyboardShouldPersistTaps='handled' только уволить клавиатура, когда кран не обрабатывается детьми (т. е. нажатие на другие textInputs или кнопки)

если у вас

<View style={{flex: 1}}>
    <TextInput keyboardType='numeric'/>
</View>

изменить на

<ScrollView contentContainerStyle={{flexGrow: 1}}
  keyboardShouldPersistTaps='handled'
>
  <TextInput keyboardType='numeric'/>
</ScrollView>

или

import {Keyboard} from 'react-native'

<TouchableWithoutFeedback onPress={Keyboard.dismiss} accessible={false}>
    <View style={{flex: 1}}>
        <TextInput keyboardType='numeric'/>
    </View>
</TouchableWithoutFeedback>

EDIT: вы также можете создать компонент более высокого порядка, чтобы отклонить клавиатуру.

import React from 'react';
import { TouchableWithoutFeedback, Keyboard, View } from 'react-native';

const DismissKeyboardHOC = (Comp) => {
  return ({ children, ...props }) => (
    <TouchableWithoutFeedback onPress={Keyboard.dismiss} accessible={false}>
      <Comp {...props}>
        {children}
      </Comp>
    </TouchableWithoutFeedback>
  );
};
const DismissKeyboardView = DismissKeyboardHOC(View)

просто используйте его так

...
render() {
    <DismissKeyboardView>
        <TextInput keyboardType='numeric'/>
    </DismissKeyboardView>
}

Примечание:accessible={false} требуется, чтобы форма ввода продолжала быть доступной через VoiceOver. Слабовидящие люди будут вам благодарны!


Это просто обновляется!--2-->и документально! Больше никаких скрытых трюков.

import { Keyboard } from 'react-native'

// Hide that keyboard!
Keyboard.dismiss()

https://github.com/facebook/react-native/pull/9925


используйте это для пользовательского увольнения

var dismissKeyboard = require('dismissKeyboard');

var TestView = React.createClass({
    render: function(){
        return (
            <TouchableWithoutFeedback 
                onPress={dismissKeyboard}>
                <View />
            </TouchableWithoutFeedback>
        )
    }
})

используйте React Native Keyboard.dismiss()

Обновил Ответ

React Native выставил статику dismiss() метод Keyboard, поэтому обновленный метод:

import { Keyboard } from 'react-native'; 

Keyboard.dismiss()

Оригинальный Ответ

используйте React Native dismissKeyboard библиотека.

у меня была очень похожая проблема, и я чувствовал, что я был единственным, кто ее не получил.

ScrollViews

если у вас ScrollView, или все, что наследуется от него, как ListView, вы можете добавить опору, которая автоматически отклонит клавиатуру на основе нажатия или перетаскивания событий.

упорка keyboardDismissMode и может иметь значение none, interactive или on-drag. Вы можете прочитать больше об этом здесь.

Обычный Вид

если у вас есть что-то другое, чем ScrollView и вы хотели бы усилить, чтобы закрыть клавиатуру, вы можете использовать простой TouchableWithoutFeedback и есть onPress используйте служебную библиотеку React Native dismissKeyboard закрыть клавиатуру для вас.

в вашем примере вы можете сделать что-то вроде этого:

var DismissKeyboard = require('dismissKeyboard'); // Require React Native's utility library.

// Wrap your view with a TouchableWithoutFeedback component like so.

<View style={styles.container}>

  <TouchableWithoutFeedback onPress={ () => { DismissKeyboard() } }>

    <View>

      <Text style={styles.welcome}>
        Welcome to React Native!
      </Text>

      <Text style={styles.instructions}>
        To get started, edit index.ios.js
      </Text>

      <Text style={styles.instructions}>
        Press Cmd+R to reload,{'\n'}
        Cmd+D or shake for dev menu
      </Text>

      <TextInput style={{height: 40, borderColor: 'gray', borderWidth: 1}} />

    </View>

  </TouchableWithoutFeedback>

</View>

Примечание: TouchableWithoutFeedback может иметь только одного ребенка, так что вы должны обернуть все в один View как показано выше.


простой ответ-использовать ScrollView вместо View и установить свойство scrollable в false (возможно, потребуется настроить некоторый стиль).

таким образом, клавиатура отклоняется в тот момент, когда я нажимаю где-то еще. Это может быть проблема с react-native, но события tap обрабатываются только с помощью ScrollViews, что приводит к описанному поведению.

Edit: благодаря jllodra. Обратите внимание, что если вы нажмете непосредственно на другой Textinput, а затем снаружи, клавиатура по-прежнему не скрывается.


я совершенно новый, чтобы реагировать, и столкнулся с той же проблемой при создании демо-приложения. Если вы используете onStartShouldSetResponder prop (описано здесь), вы можете схватить касания на простом старом React.View. Любопытно услышать мысли более опытных реакционеров об этой стратегии / если есть лучшая, но это то, что сработало для меня:

containerTouched(event) {
  this.refs.textInput.blur();
  return false;
}

render() {
  <View onStartShouldSetResponder={this.containerTouched.bind(this)}>
    <TextInput ref='textInput' />
  </View>
}

2 вещи, чтобы отметить здесь. Во-первых, как обсуждалось здесь, еще нет способа завершить редактирование всех подвидов, поэтому мы должны обратитесь к TextInput напрямую, чтобы размыть его. Во-вторых,onStartShouldSetResponder перехватывается другими сенсорными элементами управления поверх него. Итак, нажав на TouchableHighlight и т. д. (В том числе другой TextInput) в виде контейнера не событие. Однако, нажав на Image в представлении контейнера по-прежнему будет отклонять клавиатуру.


вы можете импорт keyboard С реагировать-уроженца, как показано ниже:

import { Keyboard } from 'react-native';

и в коде сделать что-то вроде этого:

render() {
    return (
      <TextInput
        onSubmit={Keyboard.dismiss}
      />
    );
  }

статический уволить()

отклоняет активную клавиатуру и удаляет фокус.


использовать ScrollView вместо View и выберите keyboardShouldPersistTaps атрибут false.

<ScrollView style={styles.container} keyboardShouldPersistTaps={false}>
    <TextInput
        placeholder="Post Title"
        onChange={(event) => this.updateTitle(event.nativeEvent.text)}
        style={styles.default}/>
 </ScrollView>

Если кому-то нужен рабочий пример того, как отклонить многострочный текстовый ввод здесь! Надеюсь, это поможет некоторым людям, документы вообще не описывают способ отклонить многострочный ввод, по крайней мере, не было конкретной ссылки на то, как это сделать. Все еще нуб, чтобы действительно разместить здесь в стеке, если кто-то думает, что это должна быть ссылка на фактический пост, для которого был написан этот фрагмент, дайте мне знать.

import React, { Component } from 'react'
import {
  Keyboard,
  TextInput,
  TouchableOpacity,
  View,
  KeyboardAvoidingView,
} from 'react-native'

class App extends Component {
  constructor(props) {
    super(props)
    this.state = {
      behavior: 'position',
    }
    this._keyboardDismiss = this._keyboardDismiss.bind(this)
  }

  componentWillMount() {
    this.keyboardDidHideListener = Keyboard.addListener('keyboardDidHide', this._keyboardDidHide);
  }

  componentWillUnmount() {
    this.keyboardDidHideListener.remove()
  }

  _keyboardDidHide() {
    Keyboard.dismiss()
  }

  render() {
    return (
      <KeyboardAvoidingView
        style={{ flex: 1 }}
        behavior={this.state.behavior}
      >
        <TouchableOpacity onPress={this._keyboardDidHide}>
          <View>
            <TextInput
              style={{
                color: '#000000',
                paddingLeft: 15,
                paddingTop: 10,
                fontSize: 18,
              }}
              multiline={true}
              textStyle={{ fontSize: '20', fontFamily: 'Montserrat-Medium' }}
              placeholder="Share your Success..."
              value={this.state.text}
              underlineColorAndroid="transparent"
              returnKeyType={'default'}
            />
          </View>
        </TouchableOpacity>
      </KeyboardAvoidingView>
    )
  }
}

обновленное использование ScrollView на React Native 0.39

<ScrollView scrollEnabled={false} contentContainerStyle={{flex: 1}} />

хотя, есть еще проблема с двумя TextInput коробок. например. Форма имени пользователя и пароля теперь будет отклонять клавиатуру при переключении между входами. Хотелось бы получить некоторые предложения, чтобы сохранить клавиатуру в живых при переключении между TextInputs при использовании ScrollView.


const dismissKeyboard = require('dismissKeyboard');
dismissKeyboard(); //dismisses it

Нет# 2;

Спасибо пользователю @ricardo-stuven за указание на это, есть еще один лучший способ отклонить клавиатуру, которую вы можете увидеть в пример в родных документах react.

простой импорт Keyboard и вызовите метод dismiss()


Если я не ошибаюсь, последняя версия React Native решила эту проблему, чтобы иметь возможность отклонить клавиатуру, нажав.


Я только что протестировал это, используя последнюю версию React Native (0.4.2), и клавиатура отклоняется при нажатии в другом месте.

и FYI: вы можете установить функцию обратного вызова, которая будет выполняться при увольнении клавиатуры, назначив ее опоре "onEndEditing".


Как насчет размещения осязаемого компонента вокруг / рядом с TextInput?

var INPUTREF = 'MyTextInput';

class TestKb extends Component {
    constructor(props) {
        super(props);
    }

    render() {
        return (
            <View style={{ flex: 1, flexDirection: 'column', backgroundColor: 'blue' }}>
                <View>
                    <TextInput ref={'MyTextInput'}
                        style={{
                            height: 40,
                            borderWidth: 1,
                            backgroundColor: 'grey'
                        }} ></TextInput>
                </View>
                <TouchableWithoutFeedback onPress={() => this.refs[INPUTREF].blur()}>
                    <View 
                        style={{ 
                            flex: 1, 
                            flexDirection: 'column', 
                            backgroundColor: 'green' 
                        }} 
                    />
                </TouchableWithoutFeedback>
            </View>
        )
    }
}

https://facebook.github.io/react-native/docs/keyboard.html

использовать

Keyboard.dismiss(0);

чтобы скрыть клавиатуру.


используя keyboardShouldPersistTaps на ScrollView вы можете передать "обработано", который имеет дело с проблемами, которые люди говорят, поставляется с использованием ScrollView. Вот что говорится в документации об использовании 'handled':the keyboard will not dismiss automatically when the tap was handled by a children, (or captured by an ancestor). здесь там, где на него ссылаются.


на ScrollView использовать

keyboardShouldPersistTaps="handled" 

это сделает вашу работу.


упаковка компонентов в TouchableWithoutFeedback может вызвать некоторое странное поведение прокрутки и другие проблемы. Я предпочитаю обернуть мое самое верхнее приложение в View С onStartShouldSetResponder свойства заполнены. Это позволит мне обрабатывать все unhandledTouches (а затем уволить клавиатуру):

``

 handleUnhandledTouches(){
   Keyboard.dismiss
   return false;
 }

 render(){
    <View style={{ flex: 1 }} onStartShouldSetResponder={this.handleUnhandledTouches}>
       <MyApp>
    </View>
  }

``


Keyboard.dismiss() сделает это. Но иногда он может потерять фокус, и клавиатура не сможет найти ссылку. Наиболее последовательный способ сделать это-поставить ref=_ref к textInput и do _ref.blur() когда вам нужно уволить, и _ref.focus() когда вам нужно вернуть клавиатуру.