Unfocus the TextInput in React Native

Я создаю приложение для Android с React Native.

Как вы можете заставить TextInput "unFocus", то есть курсор мигает внутри текстового поля. Существуют функции для isFocused() и onFocus(), но как я могу получить текстовое поле, чтобы отказаться от фокуса. Вы могли бы подумать, что он делает это автоматически, как только я нахожу вход, но это не так.

   import React, {Component} from 'react';
   import { AppRegistry, Text, View, StyleSheet, TextInput, TouchableOpacity} 
   from 'react-native';

   var SHA256 = require("crypto-js/sha256");

   export default class LoginForm extends Component{


constructor(props){
    super(props);
    this.state = {
        email: '',
        password:''
    };
}

tryLogin = () => {
    if(this.state.email=="email123" && this.state.password == "password"){
        console.log("password verified");
        this.props.navigator.replace({
            title: 'Dashboard'
        });
    }

    console.log(this.state.email);
    console.log(this.state.password);
    console.log("Hash" + SHA256(this.state.password));
}

render(){
    return(
        <View style={styles.container}>
            <TextInput 
                style={styles.input}

                placeholder="Email address" 
                placeholderTextColor="white"
                onChangeText={(email) => this.setState({email})}>
            </TextInput>
            <TextInput style={styles.input} 
                placeholder="Password" 
                placeholderTextColor="white" 
                secureTextEntry
                onChangeText={(password) => this.setState({password})}>
            </TextInput>

            <TouchableOpacity style={styles.loginButtonContainer} onPress={this.tryLogin}>
                <Text style={styles.loginButtonText}>LOGIN</Text>
            </TouchableOpacity>
        </View>
  );
}
}

AppRegistry.registerComponent('LoginForm', () => LoginForm);

const styles =  StyleSheet.create({
container: {
    padding: 20
},
input:{
    height: 40,
    backgroundColor: '#e74c3c',
    marginBottom: 20,
    color: 'white',
    paddingHorizontal: 15,
    opacity: .9
},
loginButtonContainer:{
    justifyContent: 'center',
    backgroundColor: '#bc4c3c',
    paddingVertical:15

},
loginButtonText:{
    textAlign:'center',
    color:'white',
    fontWeight: '700',
    fontSize: 24

}

   })

Это, вероятно, не будет иметь особого значения для реальных пользователей, но я просто подражаю и его надоедливый, если я хочу перезагрузить.

Ответ 1

Я думаю, что лучше использовать * ScrollView *, Keyboard.dismiss. При использовании * ScrollView *, когда пользователь нажимает за пределами textInput, клавиатура закрывается. Это сделано потому, что свойство ScrollView по умолчанию для keyboardShouldPersistTaps никогда не устанавливается. Это поведение, которое ожидает пользователь. Для отклонения клавиатуры или эквивалентного размытия textInput, когда пользователь нажимает на кнопку входа, добавьте Keyboard.dismissed() в функцию tryLogin.

import React, {Component} from 'react';
import { AppRegistry, Text, View, StyleSheet, TextInput, TouchableOpacity, ScrollView, Keyboard}
  from 'react-native';
var SHA256 = require("crypto-js/sha256");

export default class LoginForm extends Component{


  constructor(props){
    super(props);
    this.state = {
      email: '',
      password:''
    };
  }

  tryLogin = () => {
    Keyboard.dismiss();
    if(this.state.email=="email123" && this.state.password == "password"){
      console.log("password verified");
      this.props.navigator.replace({
        title: 'Dashboard'
      });
    }

    console.log(this.state.email);
    console.log(this.state.password);
    console.log("Hash" + SHA256(this.state.password));
  }

  render(){
    return(
      <ScrollView style={styles.container}>
        <TextInput
          style={styles.input}

          placeholder="Email address"
          placeholderTextColor="white"
          onChangeText={(email) => this.setState({email})}>
        </TextInput>
        <TextInput style={styles.input}
                   placeholder="Password"
                   placeholderTextColor="white"
                   secureTextEntry
                   onChangeText={(password) => this.setState({password})}>
        </TextInput>

        <TouchableOpacity style={styles.loginButtonContainer} onPress={this.tryLogin}>
          <Text style={styles.loginButtonText}>LOGIN</Text>
        </TouchableOpacity>
      </ScrollView>
    );
  }
}

AppRegistry.registerComponent('LoginForm', () => LoginForm);

const styles =  StyleSheet.create({
  container: {
    padding: 20
  },
  input:{
    height: 40,
    backgroundColor: '#e74c3c',
    marginBottom: 20,
    color: 'white',
    paddingHorizontal: 15,
    opacity: .9
  },
  loginButtonContainer:{
    justifyContent: 'center',
    backgroundColor: '#bc4c3c',
    paddingVertical:15

  },
  loginButtonText:{
    textAlign:'center',
    color:'white',
    fontWeight: '700',
    fontSize: 24

  }

})

Ответ 3

Нашел это на самом деле. Это не выглядит так красиво, и моя интуиция говорит, что это не очень "реагирующее" решение, но если вы хотите его здесь, оно есть.

<TextInput 
 style={styles.input} 
 ref="email_input"
 onSubmitEditing={() => this.refs['email_input'].blur()} 
 placeholder="Email address" 
 placeholderTextColor="white"
 onChangeText={(email) => this.setState({email})}/>

Ответ 4

Мне удалось решить это с помощью ссылки this.ref. Сначала вы присваиваете TextInput ref, например:

<input ref="myInput" />

Затем вы вызываете метод blur() для this.refs.myInput из функции

 blurTextInput(){
    this.refs.myInput.blur()
 }

Ответ 5

Ной ответ выше работает хорошо, но использование строковых ссылок теперь не рекомендуется в React и, скорее всего, скоро будет устаревшим. Вместо этого вы должны использовать функцию обратного вызова, которая вызывается при визуализации компонента, на который вы хотите сослаться.

<TextInput 
  ref={(c: any) => {
    this.textInputRef = c;
  }}
  onSubmitEditing={() => this.textInputRef.blur()} 
/>

Если вы используете Flow, вы можете указать тип вашей ссылки, поместив что-то вроде этого вне вашей функции рендеринга:

textInputRef: ?TextInput;