在本机中隐藏键盘


448

如果我点击一个文本输入,我希望能够点击其他地方以便再次关闭键盘(虽然不是回车键)。在我阅读的所有教程和博客文章中,我都没有找到与此有关的丝毫信息。

这个基本示例对于Simulator中的本地本机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>


正确的答案应该是来自下面的Eric Kim。ScrollView答案(将scrollable设置为false)不是理想的选择,如果您有多个文本输入,则不能在不关闭键盘的情况下从文本输入跳到文本输入。
hippofluff

2
对于那些想要整个应用程序解决方案的人,请参见下面的@Scottmas答案。(链接:stackoverflow.com/a/49825223/1138273
Hamed

Answers:


561

如果您有键盘,则无法解雇的问题变得更加严重keyboardType='numeric',因为无法解雇它。

用ScrollView替换View是不正确的解决方案,因为如果您有多个textInputs或buttons,则在键盘向上的同时点击它们只会关闭键盘。

正确的方法是用TouchableWithoutFeedback和封装ViewKeyboard.dismiss()

编辑:您现在可以使用 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>

编辑:您还可以创建一个高阶组件以关闭键盘。

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访问输入表单。视障人士将感谢您!


28
太好了,我唯一的评论是您可以在RN中使用官方的Keyboard API,并调用Keyboard.dismiss()而不是调用某些RN内部实用程序dismissKeyboard()。但目前两者都工作正常。
巴甫莱基奇

@PavleLekic对不起,对于延迟,我与HOC方法一起更新了答案
Eric Kim

3
这很好。我必须对箭头函数的定义稍作更改,以消除RN中的意外令牌错误: const DismissKeyboardHOC = (Comp) => {
jwinn

2
我无法onPressTouchableWithoutFeedback火灾不管我怎么努力
布拉德·莱恩

1
为什么要创建一个HoC并将其添加到您的应用程序树的根目录中
Dimitri Kopriwa,

248

这刚刚得到更新和记录!没有更多隐藏的技巧。

import { Keyboard } from 'react-native'

// Hide that keyboard!
Keyboard.dismiss()

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


4
感谢您添加。希望您的回答达到顶峰。我几乎错过了它,并使用了过时的解决方案。
牧羊犬

2
ping @MrMuetze将其更改为正确答案
jehna1

8
这不应被选为最佳答案。该问题询问在轻敲键盘时如何关闭键盘。该答案仅提供了这样做的API,而实际的最佳答案则提供了可行的实现。
jskidd3

您可以使用下一个库:KeyboardAwareScrollView
Alejandro Gonzalez

97

用于自定义解雇

var dismissKeyboard = require('dismissKeyboard');

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

它没有记录,但是react-native github repo中的样本确实使用了几次。
syarul '16

7
有趣的是,对于那些好奇的地方,它是React Native中的Utility库。这里的源:github.com/facebook/react-native/blob/master/Libraries/...
约书亚品特

1
由于某些原因,它在我尝试使用时不起作用react-native-search-bar
Peter G.

这与Keyboard.dismiss完全等效,这是更好的选择,因为已记录在案。github.com/facebook/react-native/blob/…–
里卡多·斯图

88

使用React Native的 Keyboard.dismiss()

更新的答案

React Native在上公开了静态dismiss()方法Keyboard,因此更新后的方法是:

import { Keyboard } from 'react-native'; 

Keyboard.dismiss()

原始答案

使用React Native的 dismissKeyboard库。

我有一个非常相似的问题,觉得我是唯一一个没有解决的问题。

滚动视图

如果您有个ScrollView,或任何继承自的东西(如)ListView,则可以添加一个道具,该道具将根据按下或拖动事件自动关闭键盘。

该道具keyboardDismissMode,可以有一个值noneinteractiveon-drag。您可以在这里阅读更多内容。

常规视图

如果您除了a以外的其他东西,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如上所示。


4
React Native dismiss()在Keyboard上公开了静态方法,因此更新的方法是:import { Keyboard } from 'react-native'; Keyboard.dismiss()
约书亚·品特

1
我有一个悬垂的键盘,因为我专注于输入字段时进行了重新加载。在这种情况下Keyboard.dismiss(),什么也不做,因为它的实现依赖于专注于输入,而我不再是。
pstanton

@pstanton那么,您需要做什么来关闭键盘?
Joshua Pinter18年

我找不到方法,所以我强制关闭!
pstanton

41

简单的答案是使用ScrollView而不是View并将可滚动属性设置为false(尽管可能需要调整某些样式)。

这样,当我轻按其他位置时,键盘就消失了。这可能是react-native的问题,但是tap事件似乎仅由ScrollViews处理,这导致了所描述的行为。

编辑:感谢jllodra。请注意,如果您直接点击另一个Textinput然后在外面,键盘仍然不会隐藏。


1
它可以与scrollview一起使用,但是在某些情况下,我仍会遇到一些问题,我可以单击按钮使用导航器更改视图,键盘仍然停留在底部,并且必须手动单击返回键将其关闭:(
Piyush Chauhan

1
当您在TextInput外部点击时,键盘会隐藏,但是如果您(而不是在外部点击)您在另一个TextInput中点击,然后最终在外部点击,则键盘不会隐藏。在0.6.0上测试。
jllodra

我现在看到了不同的行为。即使我直接点击另一个TextInput,在TextInput外部点击也会隐藏键盘-这是一个问题,因为您必须在另一个TextInput上点击两次才能输入内容!叹。(含RN 0.19)
莱蒂希巷

1
您可以将scrollable设置为true,并使用keyboardShouldPersistTaps = {'handled'}和keyboardDismissMode = {'on-drag'}来达到相同的效果
Eric Wiener

只有scrollview对我有用,我不知道为什么,当我输入数字键盘时接受的答案被驳回
Yvon Huynh

33

您可以像下面这样从react-native 导入keyboard

import { Keyboard } from 'react-native';

在您的代码中可能是这样的:

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

静态dismiss()

关闭活动的键盘并移开焦点。


我不需要static dismiss()。我刚刚添加Keyboard.dismiss()了onSubmit方法(其中onSubmitEditing={() => {this.onSubmit()}})
SherylHohman

30

我是React的新手,在制作演示应用程序时遇到了完全相同的问题。如果您使用onStartShouldSetResponder道具(在此描述),则可以在普通的Old上进行触摸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在容器视图中单击仍将关闭键盘。


绝对可以。但是正如您所说,如果这是正确的方法,我也很好奇。希望他们尽快解决这个问题(github.com/facebook/react-native/issues/113
mutp

太棒了,这对我有用。我的滚动视图不适用于可触摸的方法!谢谢!
James Trickey '18

24

使用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>

根据文档,keyboardShouldPersistTaps使用时,属性默认为false ScrollView。我刚刚将我的react-native更新到了最新版本,切换到第二个问题TextInput仍然存在。这样就不能关闭键盘了。您是否找到针对此特定问题的解决方案?
TurboFish

1
该文档不正确,但现已更新,请参见以下PR:github.com/facebook/react-native/issues/2150
Ryan McDermott

怎么keyboardShouldPersistTaps办?为什么在这里相关?谢谢
Lane Rettig

1
警告:不推荐使用“ keyboardShouldPersistTaps = {false}”。请改用'keyboardShouldPersistTaps =“ never”'
Milan Rakos

13

如果有人需要如何消除多行文本输入的工作示例,请继续!希望这对那里的人们有所帮助,文档完全没有描述消除多行输入的方法,至少没有关于如何执行多行输入的具体参考。如果有人认为这应该是对该摘要的实际发布的引用,请让我知道,这仍然是实际在堆栈上发布的菜鸟。

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>
    )
  }
}

11

的更新使用ScrollViewReact Native 0.39

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

虽然,两个TextInput盒子仍然存在问题。例如。现在,在输入之间切换时,用户名和密码形式将关闭键盘。希望得到一些建议,以便TextInputs在使用键盘时进行切换时保持键盘的活力ScrollView


3
似乎从a 0.40更新为,可能值为'handled',旨在解决此问题。keyboardShouldPersistTapsbooleanenum
Anshul Koka'1

11

有几种方法可以控制事件,例如onPress

import { Keyboard } from 'react-native'

onClickFunction = () => {
     Keyboard.dismiss()
}

如果要在使用滚动时关闭键盘:

<ScrollView keyboardDismissMode={'on-drag'}>
     //content
</ScrollView>

当用户在键盘外单击时,更多选项是:

<KeyboardAvoidingView behavior='padding' style={{ flex: 1}}>
    //inputs and other content
</KeyboardAvoidingView>

1
伙计们,这个问题仍然是实际的,但是问题已经有4年的历史(现在到2019年底)。现在,RN非常简单易用。我们必须借助所有才能的解决方案来复习所有能力。让我们投票这个评论!
链接

@Link嗨,谢谢!我完全同意
Idan

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

方法#2;

感谢用户@ ricardo-stuven指出了这一点,还有另一种更好的消除键盘的方法,您可以在示例中看到在react native文档中。

简单导入Keyboard并调用它的方法dismiss()


1
这与Keyboard.dismiss完全等效,这是更好的选择,因为已记录在案。github.com/facebook/react-native/blob/…–
里卡多·斯图

在我给出这个答案的时候,还没有记录。感谢您提及。我将更新我的答案。
Adeel Imran

10

将组件包装在中TouchableWithoutFeedback可能会导致一些奇怪的滚动行为和其他问题。我更喜欢将最顶层的应用程序包装在内,ViewonStartShouldSetResponder填充属性。这将允许我处理所有未处理的触摸,然后关闭键盘。重要的是,由于处理程序函数返回false,因此触摸事件像正常情况一样向上传播。

 handleUnhandledTouches(){
   Keyboard.dismiss
   return false;
 }

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

感谢您的答复@Scottmas。由于您的“奇怪的滚动行为和其他问题”评论,我最终使用它而不是TouchableWithoutFeedback。但是,如果我不是一味地相信你的话,你能详细说明一下吗?:)
库尔

8

我刚刚使用最新的React Native版本(0.4.2)对此进行了测试,当您在其他位置点击时,键盘将关闭。

仅供参考:您可以通过将键盘分配给“ onEndEditing”道具来设置在关闭键盘时执行的回调函数。


我正在调试“ onEndEditing”回调,但之前从未触发过。我将使用较新版本的react native进行调查,谢谢您的建议
TurboFish 2015年

7

如果我没记错的话,最新版本的React Native已经解决了这个问题,可以通过点击来关闭键盘。


4
您能否指出他们的代码/文档的哪一部分?我遇到了同样的问题,我真的很感激它为我指明了方向:)
冈崎美山裕太2015年

确认从RN 0.19(最新版本)开始这仍然是一个问题。
Lane Rettig

RN 0.28仍然是一个问题
hippofluff

7

如何在触摸屏周围/旁边放置可触摸的组件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>
        )
    }
}



4

键盘模块用于控制键盘事件。

  • import { Keyboard } from 'react-native'
  • 在render方法中添加以下代码。

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

您可以使用 -

Keyboard.dismiss()

static dismiss()根据反应本机文档关闭活动键盘并移开焦点。


3

首次导入键盘

import { Keyboard } from 'react-native'

然后你里面TextInput添加Keyboard.dismissonSubmitEditing道具。您应该具有以下外观:

render(){
  return(
    <View>
      <TextInput 
        onSubmitEditing={Keyboard.dismiss}
       />
    </View>
  )  
}


2

使用keyboardShouldPersistTaps中的,ScrollView您可以传入“处理”,它处理了人们说的使用ScrollView所带来的问题。这就是文档中有关使用“处理的”的内容:the keyboard will not dismiss automatically when the tap was handled by a children, (or captured by an ancestor). 是引用的地方。


这对我有用!(但是我必须将其添加到我的第3方库中react-native-keyboard-aware-scroll-view)。
Nick Grealy

1

ScrollView使用中

keyboardShouldPersistTaps="handled" 

这将完成您的工作。


1

您可以通过多种方式来处理此问题,上面的答案不包括在内returnType,因为当时没有包含在本机中。

1:您可以通过将组件包装在ScrollView中来解决此问题,默认情况下,如果我们按某个位置,则ScrollView会关闭键盘。但是如果您想使用ScrollView但禁用此效果。你可以使用pointerEvent道具来scrollView pointerEvents = 'none'

2:如果您想要关闭的按钮按下键盘,你可以只用Keyboardreact-native

import { Keyboard } from 'react-native' and inside onPress of that button, you can useKeyboard.dismiss()”。

3:单击键盘上的回车键时,也可以关闭键盘。注意:如果键盘类型为数字,则没有回车键。因此,您可以通过为其提供一个属性returnKeyType来启用它done。或者您可以使用onSubmitEditing={Keyboard.dismiss},只要我们按回车键,它就会被调用。如果您想在失去焦点时关闭键盘,可以使用onBlur属性,onBlur = {Keyboard.dismiss}


0

Keyboard.dismiss()会做的。但是有时它可能会失去焦点,并且Keyboard将无法找到参考。最一致的方法是ref=_ref在textInput上放置一个,然后_ref.blur()在需要关闭时以及_ref.focus()在需要拿回键盘时执行。



0

这是我的键盘解散并滚动到轻击的TextInput的解决方案(我将ScrollView与keyboardDismissMode属性一起使用):

import React from 'react';
import {
  Platform,
  KeyboardAvoidingView,
  ScrollView
} from 'react-native';

const DismissKeyboard = ({ children }) => {
  const isAndroid = Platform.OS === 'android';
  const behavior = isAndroid ? false : 'padding';

  return (
    <KeyboardAvoidingView
      enabled
      behavior={ behavior }
      style={{ flex: 1}}
    >
      <ScrollView
        keyboardShouldPersistTaps={'always'}
        keyboardDismissMode={'on-drag'}
      >
        { children }
      </ScrollView>
    </KeyboardAvoidingView>
  );
};

export default DismissKeyboard;

用法:

render(){
   return(
     <DismissKeyboard>
       <TextInput
        style={{height: 40, borderColor: 'gray', borderWidth: 1}}
        onChangeText={(text) => this.setState({text})}
        value={this.state.text}
      />
     </DismissKeyboard>
   );
}


0

使用这个包 react-native-keyboard-aware-scroll-view

使用该组件作为您的根组件

由于此软件包react-native-keyboard-aware-scroll-view还具有一个scrollView,因此需要将其添加到其中:

<KeyboardAwareScrollView keyboardShouldPersistTaps="handled"> <ScrollView keyboardShouldPersistTaps="handled"></ScrollView> </KeyboardAwareScrollView>

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.