如何自动将下一个TextInput聚焦在react-native上 [英] How to autofocus next TextInput on react-native
问题描述
我正在尝试创建一个受密码保护的屏幕.屏幕将使用4个数字输入作为密码.
I'm trying to create a passcode protected screen. The screen will uses 4 numeric input as the passcode.
我这样做的方法是创建一个TextInput组件,并在主屏幕中将其调用4次.
The way I'm doing this is create a TextInput Component and call it 4 times in my main screen.
我遇到的问题是,当我键入前一个TextInput的值时,TextInputs将不会关注下一个.
The problem I'm having is the TextInputs will not focus on the next one as I type the value of the previous TextInput.
我为所有PasscodeTextInput组件使用了refs(已经被告知这是一种旧方法,但是我不知道其他任何方法)
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 };
更新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);
推荐答案
您不能使用该方式将ref
转发到<TextInput>
,因为ref
是
You cannot forward the ref
to <TextInput>
using that way because ref
is one of the special props. Thus, calling this.refs.passcode2
will return you <PasscodeTextInput>
instead.
尝试更改为以下内容,以从<TextInput>
获取ref
.
Try change to the following to get the ref
from <TextInput>
.
PasscodeTextInput.js
const PasscodeTextInput = ({ inputRef, ... }) => {
...
return (
<View>
<TextInput
ref={(r) => { inputRef && inputRef(r) }}
...
/>
</View>
...
);
}
然后,将inputRef
从<PasscodeTextInput>
分配给变量,然后使用focus()
切换焦点(从RN 0.41.2
开始不推荐使用).
Then, assign the inputRef
from <PasscodeTextInput>
to a variable and use focus()
to switch focus (it is not deprecated as of RN 0.41.2
).
index.ios.js
return (
<PasscodeTextInput
autoFocus={true}
onChangeText={(event) => { event && this.passcode2.focus() }} />
<PasscodeTextInput
inputRef={(r) => { this.passcode2 = r }}
onChangeText={(event) => { event && this.passcode3.focus() }} />
<PasscodeTextInput
inputRef={(r) => { this.passcode3 = r }}
onChangeText={(event) => { event && this.passcode4.focus() }} />
<PasscodeTextInput
inputRef={(r) => { this.passcode4 = r }} />
);
P.S:event && this.passcode2.focus()
防止在尝试清除旧密码并输入新密码时切换焦点.
P.S: event && this.passcode2.focus()
prevents focus is switched when trying to clear the old passcode and enter a new one.
这篇关于如何自动将下一个TextInput聚焦在react-native上的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!