I'm trying to create a passcode protected screen. The screen will uses 4 numeric input as the passcode.
The way I'm doing this is create a TextInput Component and call it 4 times in my main screen.
The problem I'm having is the TextInputs will not focus on the next one as I type the value of the previous TextInput.
I'm using refs for all PasscodeTextInput component (I've been informed that it is a legacy method but I do not know any other way, alas).
Tried this method(without creating my own component), no luck too. METHOD
index.ios.js
import React, { Component } from 'react';
import { AppRegistry, TextInput, View, Text } from 'react-native';
import { PasscodeTextInput } from './common';
export default class ProgressBar extends Component {
render() {
const { centerEverything, container, passcodeContainer, textInputStyle} = styles;
return (
<View style={[centerEverything, container]}>
<View style={[passcodeContainer]}>
<PasscodeTextInput
autoFocus={true}
ref="passcode1"
onSubmitEditing={(event) => { this.refs.passcode2.focus() }} />
<PasscodeTextInput
ref="passcode2"
onSubmitEditing={(event) => { this.refs.passcode3.focus() }} />
<PasscodeTextInput
ref="passcode3"
onSubmitEditing={(event) => { this.refs.passcode4.focus() }}/>
<PasscodeTextInput
ref="passcode4" />
</View>
</View>
);
}
}
const styles = {
centerEverything: {
justifyContent: 'center',
alignItems: 'center',
},
container: {
flex: 1,
backgroundColor: '#E7DDD3',
},
passcodeContainer: {
flexDirection: 'row',
},
}
AppRegistry.registerComponent('ProgressBar', () => ProgressBar);
PasscodeTextInput.js
import React from 'react';
import {
View,
Text,
TextInput,
Dimensions
} from 'react-native';
const deviceWidth = require('Dimensions').get('window').width;
const deviceHeight = require('Dimensions').get('window').height;
const PasscodeTextInput = ({ ref, autoFocus, onSubmitEditing, onChangeText, value}) => {
const { inputStyle, underlineStyle } = styles;
return(
<View>
<TextInput
ref={ref}
autoFocus={autoFocus}
onSubmitEditing={onSubmitEditing}
style={[inputStyle]}
maxLength={1}
keyboardType="numeric"
placeholderTextColor="#212121"
secureTextEntry={true}
onChangeText={onChangeText}
value={value}
/>
<View style={underlineStyle} />
</View>
);
}
const styles = {
inputStyle: {
height: 80,
width: 60,
fontSize: 50,
color: '#212121',
fontSize: 40,
padding: 18,
margin: 10,
marginBottom: 0
},
underlineStyle: {
width: 60,
height: 4,
backgroundColor: '#202020',
marginLeft: 10
}
}
export { PasscodeTextInput };
Update 1
index.ios.js
import React, { Component } from 'react';
import { AppRegistry, TextInput, View, Text } from 'react-native';
import { PasscodeTextInput } from './common';
export default class ProgressBar extends Component {
constructor() {
super()
this.state = {
autoFocus1: true,
autoFocus2: false,
autoFocus3: false,
autoFocus4: false,
}
}
onTextChanged(t) { //callback for immediate state change
if (t == 2) { this.setState({ autoFocus1: false, autoFocus2: true }, () => { console.log(this.state) }) }
if (t == 3) { this.setState({ autoFocus2: false, autoFocus3: true }, () => { console.log(this.state) }) }
if (t == 4) { this.setState({ autoFocus3: false, autoFocus4: true }, () => { console.log(this.state) }) }
}
render() {
const { centerEverything, container, passcodeContainer, testShit, textInputStyle } = styles;
return (
<View style={[centerEverything, container]}>
<View style={[passcodeContainer]}>
<PasscodeTextInput
autoFocus={this.state.autoFocus1}
onChangeText={() => this.onTextChanged(2)} />
<PasscodeTextInput
autoFocus={this.state.autoFocus2}
onChangeText={() => this.onTextChanged(3)} />
<PasscodeTextInput
autoFocus={this.state.autoFocus3}
onChangeText={() => this.onTextChanged(4)} />
<PasscodeTextInput
autoFocus={this.state.autoFocus4} />
</View>
</View>
);
}
}
const styles = {
centerEverything: {
justifyContent: 'center',
alignItems: 'center',
},
container: {
flex: 1,
backgroundColor: '#E7DDD3',
},
passcodeContainer: {
flexDirection: 'row',
},
}
AppRegistry.registerComponent('ProgressBar', () => ProgressBar);
There is a defaultProp for TextInput where one can focus after component mounted.
autoFocus
If true, focuses the input on componentDidMount, the default value is false. for more information please read the related Docs.
After componentDidUpdate
it won't work properly. In that case, one can use ref
to focus programmatically.