我正在尝试创建受密码保护的屏幕。屏幕将使用4个数字输入作为密码。
我这样做的方法是创建一个TextInput组件并在我的主屏幕中调用它4次。
我遇到的问题是,当我键入前一个TextInput的值时,TextInputs不会关注下一个。
我在所有PasscodeTextInput组件中都使用了refs(我已经被告知这是一种遗留方法,但我不知道其他任何方式,唉)。
试过这个方法(没有创建我自己的组件),也没有运气。 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);
答案 0 :(得分:9)
TextInput有一个defaultProp,可以在安装组件后对焦。
<强> 自动对焦 强>
如果为true,则将输入聚焦在componentDidMount上,默认值为false。有关更多信息,请阅读相关的Docs。
componentDidUpdate
之后,它无法正常工作。在这种情况下,可以使用ref
以编程方式进行聚焦。
答案 1 :(得分:4)
我们采用不同的方法处理这种风格的屏幕。
而不是管理4个单独的TextInput并处理每个TextInput的焦点导航(当用户删除一个字符时再返回),我们在屏幕上有一个TextInput但是不可见(即.xpx x 0px)宽有焦点,maxLength和键盘配置等。
此TextInput接收来自用户的输入,但实际上看不到,因为每输入一个字符,我们将输入的文本渲染为一系列简单的视图/文本元素,其风格与上面的屏幕非常相似。
这种方法对我们来说效果很好,无需管理下一步&#39;或者之前的&#39; TextInput将重点放在。
之后答案 2 :(得分:2)
你可以像Jason所说的那样使用焦点方法onChangeText
,除此之外,添加maxLength={1}
可以让你立即跳转到下一个输入,而无需检查添加的内容。 (只是注意到它的已弃用,但这仍然是我解决问题的方法,并且应该在v0.36之前完成,并且link解释了如何更新已弃用的函数。)< / p>
<TextInput
ref="first"
style={styles.inputMini}
maxLength={1}
keyboardType="numeric"
returnKeyType='next'
blurOnSubmit={false}
placeholderTextColor="gray"
onChangeText={(val) => {
this.refs['second'].focus()
}}
/>
<TextInput
ref="second"
style={styles.inputMini}
maxLength={1}
keyboardType="numeric"
returnKeyType='next'
blurOnSubmit={false}
placeholderTextColor="gray"
onChangeText={(val) => {
this.refs['third'].focus()
}}
/>
...
请注意我对refs的使用也已弃用,但我刚刚复制了代码,因为我可以保证你当时正在使用(希望现在也可以使用)。
最后,此类实现的主要问题是,一旦您尝试使用退格键移除数字,您的焦点将跳转到下一个,从而导致严重的UX问题。但是,您可以侦听退格键输入并执行不同的操作,而不是专注于下一个输入。因此,如果您选择使用此类实施,我将在此处留下link以供您进一步调查。
以前描述过问题的Hacky解决方案:如果您在执行任何操作之前检查onChangeText
道具中输入了什么,如果值为数字,您可以跳转到下一个输入强>,否则(那是退格),跳回来。 (刚想出这个想法,我还没试过。)
答案 3 :(得分:1)
我认为问题在于onSubmitEditing
是在你点击&#34;返回&#34;或者&#34;输入&#34;常规键盘上的按键...键盘上没有其中一个按钮。
假设您希望每个输入只有一个字符,您可以查看onChangeText
,然后检查文本是否长度为1,如果长度确实为1则调用焦点。
答案 4 :(得分:0)
<TextInput
ref={input => {
this.nameOrId = input;
}}
/>
<TouchableOpacity
onPress={()=>{
this.nameOrId.focus()
}}
>
<Text>Click</Text>
</TouchableOpacity>
答案 5 :(得分:0)
我用这个代码解决: const 验证代码:React.FC = ({ pass, onFinish }) => {
const inputsRef = useRef<Input[] | null[]>([]);
const [active, setActive] = useState<number>(0);
const onKeyPress = ({ nativeEvent }:
NativeSyntheticEvent<TextInputKeyPressEventData>) => {
if (nativeEvent.key === "Backspace") {
if (active !== 0) {
inputsRef.current[active - 1]?.focus();
return setActive(active - 1);
}
} else {
inputsRef.current[active + 1]?.focus();
return setActive(active + 1);
}
return null;
};
return (
<View style={styles.container}>
<StyledInput
onKeyPress={onKeyPress}
autoFocus={active === 0}
ref={(r) => {
inputsRef.current[0] = r;
}}
/>
<StyledInput
onKeyPress={onKeyPress}
autoFocus={active === 1}
ref={(r) => {
inputsRef.current[1] = r;
}}
/>
<StyledInput
onKeyPress={onKeyPress}
autoFocus={active === 2}
ref={(r) => {
inputsRef.current[2] = r;
}}
/>
<StyledInput
onKeyPress={onKeyPress}
autoFocus={active === 3}
ref={(r) => {
inputsRef.current[3] = r;
}}
/>
</View>
);
};
export default VerifyCode;
我在所有输入中放了一个 ref,当 onKeyPress 触发时,该函数验证是否必须返回或转到下一个输入