ios React Native:按下“下一步”键盘按钮后如何选择下一个TextInput?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/32748718/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-31 07:48:00  来源:igfitidea点击:

React Native: How to select the next TextInput after pressing the "next" keyboard button?

iosreact-native

提问by andreaswienes

I defined two TextInput fields as follows:

我定义了两个 TextInput 字段,如下所示:

<TextInput 
   style = {styles.titleInput}
   returnKeyType = {"next"}
   autoFocus = {true}
   placeholder = "Title" />
<TextInput
   style = {styles.descriptionInput}          
   multiline = {true}
   maxLength = {200}
   placeholder = "Description" />

But after pressing the "next" button on my keyboard, my react-native app isn't jumping to the second TextInput field. How can I achieve that?

但是在按下键盘上的“下一步”按钮后,我的 react-native 应用程序不会跳转到第二个 TextInput 字段。我怎样才能做到这一点?

Thanks!

谢谢!

回答by boredgames

Set the second TextInputfocus, when the previous TextInput's onSubmitEditingis triggered.

将第二个TextInput焦点,当先前TextInputonSubmitEditing被触发。

Try this

尝试这个

  1. Adding a Ref to second TextInput
    ref={(input) => { this.secondTextInput = input; }}

  2. Bind focus function to first TextInput's onSubmitEditing event.
    onSubmitEditing={() => { this.secondTextInput.focus(); }}

  3. Remember to set blurOnSubmit to false, to prevent keyboard flickering.
    blurOnSubmit={false}

  1. 将 Ref 添加到第二个 TextInput
    ref={(input) => { this.secondTextInput = input; }}

  2. 将焦点函数绑定到第一个 TextInput的 onSubmitEditing 事件。
    onSubmitEditing={() => { this.secondTextInput.focus(); }}

  3. 请记住将 blurOnSubmit 设置为 false,以防止键盘闪烁。
    blurOnSubmit={false}

When all done, it should looks like this.

全部完成后,它应该是这样的。

<TextInput
    placeholder="FirstTextInput"
    returnKeyType="next"
    onSubmitEditing={() => { this.secondTextInput.focus(); }}
    blurOnSubmit={false}
/>

<TextInput
    ref={(input) => { this.secondTextInput = input; }}
    placeholder="secondTextInput"
/>

回答by Stedman Blake

You can do this without using refs. This approach is preferred, since refs can lead to fragile code. The React docsadvise finding other solutions where possible:

您可以在不使用 refs 的情况下执行此操作。这种方法是首选,因为 refs 会导致脆弱的代码。该阵营文档奉劝如果可能的话寻找其他的解决方案:

If you have not programmed several apps with React, your first inclination is usually going to be to try to use refs to "make things happen" in your app. If this is the case, take a moment and think more critically about where state should be owned in the component hierarchy. Often, it becomes clear that the proper place to "own" that state is at a higher level in the hierarchy. Placing the state there often eliminates any desire to use refs to "make things happen" – instead, the data flow will usually accomplish your goal.

如果你还没有用 React 编写过几个应用程序,你的第一个倾向通常是尝试使用 refs 在你的应用程序中“使事情发生”。如果是这种情况,请花点时间更批判性地思考状态应该在组件层次结构中的哪个位置拥有。通常,很明显,“拥有”该状态的适当位置位于层次结构中的更高级别。将状态放在那里通常会消除任何使用 refs 来“使事情发生”的愿望——相反,数据流通常会实现你的目标。

Instead, we'll use a state variable to focus the second input field.

相反,我们将使用状态变量来聚焦第二个输入字段。

  1. Add a state variable that we'll pass as a prop to the DescriptionInput:

    initialState() {
      return {
        focusDescriptionInput: false,
      };
    }
    
  2. Define a handler method that will set this state variable to true:

    handleTitleInputSubmit() {
      this.setState(focusDescriptionInput: true);
    }
    
  3. Upon submitting / hitting enter / next on the TitleInput, we'll call handleTitleInputSubmit. This will set focusDescriptionInputto true.

    <TextInput 
       style = {styles.titleInput}
       returnKeyType = {"next"}
       autoFocus = {true}
       placeholder = "Title" 
       onSubmitEditing={this.handleTitleInputSubmit}
    />
    
  4. DescriptionInput's focusprop is set to our focusDescriptionInputstate variable. So, when focusDescriptionInputchanges (in step 3), DescriptionInputwill re-render with focus={true}.

    <TextInput
       style = {styles.descriptionInput}          
       multiline = {true}
       maxLength = {200}
       placeholder = "Description" 
       focus={this.state.focusDescriptionInput}
    />
    
  1. 添加一个我们将作为道具传递给的状态变量DescriptionInput

    initialState() {
      return {
        focusDescriptionInput: false,
      };
    }
    
  2. 定义一个将这个状态变量设置为 true 的处理程序方法:

    handleTitleInputSubmit() {
      this.setState(focusDescriptionInput: true);
    }
    
  3. 在 上提交/点击 enter/next 后TitleInput,我们将调用handleTitleInputSubmit. 这将设置focusDescriptionInput为 true。

    <TextInput 
       style = {styles.titleInput}
       returnKeyType = {"next"}
       autoFocus = {true}
       placeholder = "Title" 
       onSubmitEditing={this.handleTitleInputSubmit}
    />
    
  4. DescriptionInputfocusprop 设置为我们的focusDescriptionInput状态变量。因此,当focusDescriptionInput更改(在第 3 步中)时,DescriptionInput将使用focus={true}.

    <TextInput
       style = {styles.descriptionInput}          
       multiline = {true}
       maxLength = {200}
       placeholder = "Description" 
       focus={this.state.focusDescriptionInput}
    />
    

This is a nice way to avoid using refs, since refs can lead to more fragile code :)

这是避免使用 refs 的好方法,因为 refs 会导致更脆弱的代码:)

EDIT: h/t to @LaneRettig for pointing out that you'll need to wrap the React Native TextInput with some added props & methods to get it to respond to focus:

编辑:@LaneRettig 的 h/t 指出您需要使用一些添加的道具和方法包装 React Native TextInput 以使其响应focus

    // Props:
    static propTypes = { 
        focus: PropTypes.bool,
    } 

    static defaultProps = { 
        focus: false,
    } 

    // Methods:
    focus() {
        this._component.focus(); 
    } 

    componentWillReceiveProps(nextProps) {
        const {focus} = nextProps; 

        focus && this.focus(); 
    }

回答by Mitch

As of React Native 0.36, calling focus()(as suggested in several other answers) on a text input node isn't supported any more. Instead, you can use the TextInputStatemodule from React Native. I created the following helper module to make this easier:

从 React Native 0.36 开始,focus()不再支持在文本输入节点上调用(如其他几个答案中所建议的那样)。相反,您可以使用TextInputStateReact Native 中的模块。我创建了以下帮助器模块以使其更容易:

// TextInputManager
//
// Provides helper functions for managing the focus state of text
// inputs. This is a hack! You are supposed to be able to call
// "focus()" directly on TextInput nodes, but that doesn't seem
// to be working as of ReactNative 0.36
//
import { findNodeHandle } from 'react-native'
import TextInputState from 'react-native/lib/TextInputState'


export function focusTextInput(node) {
  try {
    TextInputState.focusTextInput(findNodeHandle(node))
  } catch(e) {
    console.log("Couldn't focus text input: ", e.message)
  }
}

You can, then, call the focusTextInputfunction on any "ref" of a TextInput. For example:

然后,您可以focusTextInput在 a 的任何“引用”上调用该函数TextInput。例如:

...
<TextInput onSubmit={() => focusTextInput(this.refs.inputB)} />
<TextInput ref="inputB" />
...

回答by zackify

I created a small library that does this, no code change needed other than replacing your wrapping view and import of TextInput:

我创建了一个执行此操作的小型库,除了替换您的包装视图和 TextInput 导入之外,无需更改代码:

import { Form, TextInput } from 'react-native-autofocus'

export default () => (
  <Form>
    <TextInput placeholder="test" />
    <TextInput placeholder="test 2" />
  </Form>
)

https://github.com/zackify/react-native-autofocus

https://github.com/zackify/react-native-autofocus

Explained in detail here: https://zach.codes/autofocus-inputs-in-react-native/

在这里详细解释:https: //zach.codes/autofocus-inputs-in-react-native/

回答by kuhr

Using react-native 0.45.1 I also encountered problems trying to set focus on a password TextInput after pressing return key on a username TextInput.

使用 react-native 0.45.1 我也遇到了在用户名 TextInput 上按下回车键后试图将焦点设置在密码 TextInput 上的问题。

After having tried most of the top rated solutions here on SO I found a solution on github that fulfilled my needs: https://github.com/shoutem/ui/issues/44#issuecomment-290724642

在 SO 上尝试了大多数最受好评的解决方案后,我在 github 上找到了一个满足我需求的解决方案:https: //github.com/shoutem/ui/issues/44#issuecomment-290724642

To sum it up:

把它们加起来:

import React, { Component } from 'react';
import { TextInput as RNTextInput } from 'react-native';

export default class TextInput extends Component {
    render() {
        const { props } = this;

        return (
            <RNTextInput
                {...props}
                ref={(input) => props.inputRef && props.inputRef(input)}
            />
        );
    }
}

And then I use it like this:

然后我像这样使用它:

import React, {Component} from 'react';
import {
    View,
} from 'react-native';
import TextInput from "../../components/TextInput";

class Login extends Component {
    constructor(props) {
        super(props);
        this.passTextInput = null
    }

    render() {
        return (
            <View style={{flex:1}}>
                <TextInput
                    style={{flex:1}}
                    placeholder="Username"
                    onSubmitEditing={(event) => {
                        this.passTextInput.focus()
                    }}
                />

                <TextInput
                    style={{flex:1}}
                    placeholder="Password"
                    inputRef={(input) => {
                        this.passTextInput = input
                    }}
                />
            </View>
        )
    }
}

回答by Eli Johnson

Thought I would share my solution using a function component... 'this' not needed!

以为我会使用功能组件分享我的解决方案......不需要'这个'!

React 16.12.0 and React Native 0.61.5

React 16.12.0 和 React Native 0.61.5

Here is an example of my component:

这是我的组件的示例:

import React, { useRef } from 'react'
...


const MyFormComponent = () => {

  const ref_input2 = useRef();
  const ref_input3 = useRef();

  return (
    <>
      <TextInput
        placeholder="Input1"
        autoFocus={true}
        returnKeyType="next"
        onSubmitEditing={() => ref_input2.current.focus()}
      />
      <TextInput
        placeholder="Input2"
        returnKeyType="next"
        onSubmitEditing={() => ref_input3.current.focus()}
        ref={ref_input2}
      />
      <TextInput
        placeholder="Input3"
        ref={ref_input3}
      />
    </>
  )
}

I dunno, hope this helps someone =)

我不知道,希望这对某人有帮助 =)

回答by Wishmaster

For me on RN 0.50.3 it's possible with this way:

对于我在 RN 0.50.3 上,可以通过这种方式:

<TextInput 
  autoFocus={true} 
  onSubmitEditing={() => {this.PasswordInputRef._root.focus()}} 
/>

<TextInput ref={input => {this.PasswordInputRef = input}} />

You must see this.PasswordInputRef._root.focus()

你必须看到这个.PasswordInputRef。_root.focus()

回答by Lane Rettig

If you happen to be using tcomb-form-nativeas I am, you can do this, too. Here's the trick: instead of setting the props of the TextInputdirectly, you do it via options. You can refer to the fields of the form as:

如果你碰巧tcomb-form-native像我一样使用,你也可以这样做。诀窍是:不是TextInput直接设置 的道具,而是通过options. 您可以将表单的字段称为:

this.refs.form.getComponent('password').refs.input.focus()

So the final product looks something like this:

所以最终产品看起来像这样:

var t = require('tcomb-form-native');
var Form = t.form.Form;

var MyForm = t.struct({
  field1:     t.String,
  field2:     t.String,
});

var MyComponent = React.createClass({

  _getFormOptions () {
    return {
      fields: {
        field1: {
          returnKeyType: 'next',
          onSubmitEditing: () => {this.refs.form.getComponent('field2').refs.input.focus()},
        },
      },
    };
  },

  render () {

    var formOptions = this._getFormOptions();

    return (
      <View style={styles.container}>
        <Form ref="form" type={MyForm} options={formOptions}/>
      </View>
    );
  },
});

(Credit to remcoanker for posting the idea here: https://github.com/gcanti/tcomb-form-native/issues/96)

(感谢 remcoanker 在此处发布这个想法:https: //github.com/gcanti/tcomb-form-native/issues/96

回答by Janaka Pushpakumara

This is the way I achieved it. And the example below has used the React.createRef() API introduced in React 16.3.

这就是我实现它的方式。下面的示例使用了 React 16.3 中引入的 React.createRef() API。

class Test extends React.Component {
  constructor(props) {
    super(props);
    this.secondTextInputRef = React.createRef();
  }

  render() {
    return(
        <View>
            <TextInput
                placeholder = "FirstTextInput"
                returnKeyType="next"
                onSubmitEditing={() => { this.secondTextInputRef.current.focus(); }}
            />
            <TextInput
                ref={this.secondTextInputRef}
                placeholder = "secondTextInput"
            />
        </View>
    );
  }
}

I think this will help you.

我认为这会对你有所帮助。

回答by Rodrigo Tessarollo

My scenario is < CustomBoladonesTextInput />wrapping a RN < TextInput />.

我的场景是< CustomBoladonesTextInput />包装一个 RN < TextInput />

I solved this issue as follow:

我解决了这个问题如下:

My form looks like:

我的表格看起来像:

  <CustomBoladonesTextInput 
      onSubmitEditing={() => this.customInput2.refs.innerTextInput2.focus()}
      returnKeyType="next"
      ... />

  <CustomBoladonesTextInput 
       ref={ref => this.customInput2 = ref}
       refInner="innerTextInput2"
       ... />

On CustomBoladonesTextInput's component definition, I pass the refField to the inner ref prop like this:

在 CustomBoladonesTextInput 的组件定义中,我将 refField 传递给内部 ref 属性,如下所示:

   export default class CustomBoladonesTextInput extends React.Component {
      render() {        
         return (< TextInput ref={this.props.refInner} ... />);     
      } 
   }

And voila. Everything get back works again. Hope this helps

瞧。一切恢复正常。希望这可以帮助