run react new create cli apps app ios react-native

new - react native run ios



React Native: ¿Cómo seleccionar la siguiente entrada de texto después de presionar el botón de teclado "siguiente"? (17)

A partir de React Native 0.36, ya no se admite llamar a focus() (como se sugiere en varias otras respuestas) en un nodo de entrada de texto. En su lugar, puede usar el módulo TextInputState de React Native. Creé el siguiente módulo auxiliar para facilitar esto:

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

Entonces, puede llamar a la función focusTextInput en cualquier "referencia" de un TextInput . Por ejemplo:

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

Definí dos campos TextInput de la siguiente manera:

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

Pero después de presionar el botón "siguiente" en mi teclado, mi aplicación nativa de reacción no salta al segundo campo TextInput. ¿Cómo puedo lograr eso?

¡Gracias!


Aquí una solución de reactivo para un componente de entrada que tiene una propiedad: focus.

El campo se enfocará mientras este accesorio esté establecido en verdadero y no tendrá foco mientras sea falso.

Desafortunadamente, este componente necesita tener un: ref definido, no pude encontrar otra forma de llamar a .focus () en él. Estoy contento con las sugerencias.

(defn focusable-input [init-attrs] (r/create-class {:display-name "focusable-input" :component-will-receive-props (fn [this new-argv] (let [ref-c (aget this "refs" (:ref init-attrs)) focus (:focus (ru/extract-props new-argv)) is-focused (.isFocused ref-c)] (if focus (when-not is-focused (.focus ref-c)) (when is-focused (.blur ref-c))))) :reagent-render (fn [attrs] (let [init-focus (:focus init-attrs) auto-focus (or (:auto-focus attrs) init-focus) attrs (assoc attrs :auto-focus auto-focus)] [input attrs]))}))

https://gist.github.com/Knotschi/6f97efe89681ac149113ddec4c396cc5


Así es como lo logré. Y el siguiente ejemplo ha utilizado la API React.createRef () presentada en React 16.3.

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

Creo que esto te ayudará.



Establezca el segundo foco TextInput , cuando se activa onSubmitEditing TextInput anterior.

Prueba esto

  1. Agregar una referencia a la segunda entrada de texto
    ref={(input) => { this.secondTextInput = input; }}

  2. Enlace la función de enfoque al primer evento onSubmitEditing de TextInput .
    onSubmitEditing={() => { this.secondTextInput.focus(); }}

  3. Recuerde establecer blurOnSubmit en false, para evitar el parpadeo del teclado.
    blurOnSubmit={false}

Cuando todo esté listo, debería verse así.

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


Hay una manera de capturar pestañas en un TextInput . Es hacky, pero mejor que nothing .

Defina un controlador onChangeText que compare el nuevo valor de entrada con el antiguo, buscando un /t . Si encuentra uno, avance el campo como se muestra en @boredgames

Suponiendo que el username variable contiene el valor para el nombre de usuario y setUsername envía una acción para cambiarlo en la tienda (estado del componente, tienda redux, etc.), haga algo como esto:

<TextInput onSubmitEditing={() => { this.focusNextField(''two''); }} returnKeyType="next" blurOnSubmit={false}/> <TextInput ref={input => { this.inputs[''two''] = input; }}/>


Mi escenario es <CustomBoladonesTextInput /> envolviendo un RN <TextInput /> .

Resolví este problema de la siguiente manera:

Mi forma se ve así:

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

En la definición del componente CustomBoladonesTextInput, paso el refField al accesorio de referencia interno de esta manera:

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

Y voilá. Todo vuelve a funcionar de nuevo. Espero que esto ayude


Para mí en RN 0.50.3 es posible de esta manera:

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

Debes ver esto.PasswordInputRef. _root .focus ()


Para que la solución aceptada funcione si su TextInput está dentro de otro componente, deberá "hacer estallar" la referencia de ref al contenedor principal.

// MyComponent render() { <View> <TextInput ref={(r) => this.props.onRef(r)} { ...this.props }/> </View> } // MyView render() { <MyComponent onSubmitEditing={(evt) => this.myField2.focus()}/> <MyComponent onRef={(r) => this.myField2 = r}/> }


Pruebe esta solución en los problemas de GitHub de React Native.

https://github.com/facebook/react-native/pull/2149#issuecomment-129262565

Debe usar el accesorio de referencia para el componente TextInput.
Luego, necesita crear una función que se llame a onSubmitEditing prop que mueva el foco en la segunda referencia TextInput.

var InputScreen = React.createClass({ _focusNextField(nextField) { this.refs[nextField].focus() }, render: function() { return ( <View style={styles.container}> <TextInput ref=''1'' style={styles.input} placeholder=''Normal'' returnKeyType=''next'' blurOnSubmit={false} onSubmitEditing={() => this._focusNextField(''2'')} /> <TextInput ref=''2'' style={styles.input} keyboardType=''email-address'' placeholder=''Email Address'' returnKeyType=''next'' blurOnSubmit={false} onSubmitEditing={() => this._focusNextField(''3'')} /> <TextInput ref=''3'' style={styles.input} keyboardType=''url'' placeholder=''URL'' returnKeyType=''next'' blurOnSubmit={false} onSubmitEditing={() => this._focusNextField(''4'')} /> <TextInput ref=''4'' style={styles.input} keyboardType=''numeric'' placeholder=''Numeric'' blurOnSubmit={false} onSubmitEditing={() => this._focusNextField(''5'')} /> <TextInput ref=''5'' style={styles.input} keyboardType=''numbers-and-punctuation'' placeholder=''Numbers & Punctuation'' returnKeyType=''done'' /> </View> ); } });


Puedes hacer esto sin usar referencias . Se prefiere este enfoque, ya que las referencias pueden conducir a un código frágil . Los documentos de React aconsejan encontrar otras soluciones cuando sea posible:

Si no ha programado varias aplicaciones con React, su primera inclinación será tratar de usar referencias para "hacer que las cosas sucedan" en su aplicación. Si este es el caso, tómese un momento y piense más críticamente sobre dónde debe pertenecer el estado en la jerarquía de componentes. A menudo, queda claro que el lugar adecuado para "poseer" ese estado está en un nivel superior en la jerarquía. Colocar el estado allí a menudo elimina cualquier deseo de usar referencias para "hacer que las cosas sucedan"; en cambio, el flujo de datos generalmente logrará su objetivo.

En su lugar, utilizaremos una variable de estado para enfocar el segundo campo de entrada.

  1. Agregue una variable de estado que pasaremos como accesorio a la DescriptionInput :

    initialState() { return { focusDescriptionInput: false, }; }

  2. Defina un método de controlador que establezca esta variable de estado en verdadero:

    handleTitleInputSubmit() { this.setState(focusDescriptionInput: true); }

  3. Al enviar / presionar enter / next en TitleInput , llamaremos a handleTitleInputSubmit . Esto establecerá focusDescriptionInput en verdadero.

    <TextInput style = {styles.titleInput} returnKeyType = {"next"} autoFocus = {true} placeholder = "Title" onSubmitEditing={this.handleTitleInputSubmit} />

  4. El accesorio de focus DescriptionInput se establece en nuestra variable de estado focusDescriptionInput . Entonces, cuando focusDescriptionInput cambia (en el paso 3), DescriptionInput se volverá a representar con focus={true} .

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

Esta es una buena manera de evitar el uso de referencias, ya que las referencias pueden conducir a un código más frágil :)

EDITAR: h / t a @LaneRettig para señalar que necesitará ajustar React Native TextInput con algunos accesorios y métodos adicionales para que responda al focus :

// Props: static propTypes = { focus: PropTypes.bool, } static defaultProps = { focus: false, } // Methods: focus() { this._component.focus(); } componentWillReceiveProps(nextProps) { const {focus} = nextProps; focus && this.focus(); }


Si está utilizando tcomb-form-native como yo, también puede hacerlo. Aquí está el truco: en lugar de configurar los accesorios de TextInput directamente, lo haces a través de options . Puede referirse a los campos del formulario como:

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

Entonces el producto final se ve así:

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

(Crédito a remcoanker por publicar la idea aquí: https://github.com/gcanti/tcomb-form-native/issues/96 )


Si está utilizando NativeBase como componentes de la interfaz de usuario, puede usar este ejemplo

<Item floatingLabel> <Label>Title</Label> <Input returnKeyType = {"next"} autoFocus = {true} onSubmitEditing={(event) => { this._inputDesc._root.focus(); }} /> </Item> <Item floatingLabel> <Label>Description</Label> <Input getRef={(c) => this._inputDesc = c} multiline={true} style={{height: 100}} /> onSubmitEditing={(event) => { this._inputLink._root.focus(); }} /> </Item>


Usando react-native 0.45.1 también encontré problemas al tratar de establecer el foco en una contraseña TextInput después de presionar la tecla de retorno en un nombre de usuario TextInput.

Después de haber probado la mayoría de las soluciones mejor calificadas aquí en SO, encontré una solución en github que satisfizo mis necesidades: https://github.com/shoutem/ui/issues/44#issuecomment-290724642

Para resumirlo:

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

Y luego lo uso así:

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


Usar referencias de devolución de llamada en lugar de las referencias de cadena legacy :

<TextInput style = {styles.titleInput} returnKeyType = {"next"} autoFocus = {true} placeholder = "Title" onSubmitEditing={() => {this.nextInput.focus()}} /> <TextInput style = {styles.descriptionInput} multiline = {true} maxLength = {200} placeholder = "Description" ref={nextInput => this.nextInput = nextInput} />


en su componente:

<TextInput placeholder="Nombre" ref="1" editable={true} returnKeyType="next" underlineColorAndroid={''#4DB6AC''} blurOnSubmit={false} value={this.state.First_Name} onChangeText={First_Name => this.setState({ First_Name })} onSubmitEditing={() => this.focusNextField(''2'')} placeholderTextColor="#797a7a" style={{ marginBottom: 10, color: ''#808080'', fontSize: 15, width: ''100%'', }} /> <TextInput placeholder="Apellido" ref="2" editable={true} returnKeyType="next" underlineColorAndroid={''#4DB6AC''} blurOnSubmit={false} value={this.state.Last_Name} onChangeText={Last_Name => this.setState({ Last_Name })} onSubmitEditing={() => this.focusNextField(''3'')} placeholderTextColor="#797a7a" style={{ marginBottom: 10, color: ''#808080'', fontSize: 15, width: ''100%'', }} />

Nota: utilicé ._root porque es una referencia a TextInput en NativeBase''Library ''Input

y en tus entradas de texto como esta

focusNextField(nextField) { this.refs[nextField].focus(); }


function tabGuard (newValue, oldValue, callback, nextCallback) { if (newValue.indexOf(''/t'') >= 0 && oldValue.indexOf(''/t'') === -1) { callback(oldValue) nextCallback() } else { callback(newValue) } } class LoginScene { focusNextField = (nextField) => { this.refs[nextField].focus() } focusOnPassword = () => { this.focusNextField(''password'') } handleUsernameChange = (newValue) => { const { username } = this.props // or from wherever const { setUsername } = this.props.actions // or from wherever tabGuard(newValue, username, setUsername, this.focusOnPassword) } render () { const { username } = this.props return ( <TextInput ref=''username'' placeholder=''Username'' autoCapitalize=''none'' autoCorrect={false} autoFocus keyboardType=''email-address'' onChangeText={handleUsernameChange} blurOnSubmit={false} onSubmitEditing={focusOnPassword} value={username} /> ) } }

y agregar método

constructor(props) { super(props); this.focusNextField = this .focusNextField .bind(this); // to store our input refs this.inputs = {}; } focusNextField(id) { console.log("focus next input: " + id); this .inputs[id] ._root .focus(); }