如何自动对焦反应本机上的下一个TextInput
我试图创建一个密码保护屏幕。屏幕将使用4位数字输入作为密码。如何自动对焦反应本机上的下一个TextInput
我这样做的方式是创建一个TextInput组件,并在我的主屏幕中调用它4次。
我遇到的问题是TextInputs将不会专注于下一个,因为我键入以前的TextInput的值。
我使用所有PasscodeTextInput组件的参考(我已被告知它是一个传统的方法,但我不知道任何其他方式,唉)。
试过这种方法(没有创建我自己的组件),也没有运气。 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
是special props之一。因此,致电this.refs.passcode2
将返回您<PasscodeTextInput>
。
尝试更改以下以从<TextInput>
获取ref
。
PasscodeTextInput.js
const PasscodeTextInput = ({ inputRef, ... }) => {
...
return (
<View>
<TextInput
ref={(r) => { inputRef && inputRef(r) }}
...
/>
</View>
...
);
}
然后,分配从<PasscodeTextInput>
的inputRef
给一个变量,并使用focus()
切换焦点和(未弃用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()
防止焦点试图清除旧密码,然后输入一个新的时切换。
这是神奇的。谢谢! :) –
@ J.doe:感谢代码。您是否删除了删除按键? – djk
我认为这个问题是onSubmitEditing
是当你点击“返回”或“ENTER”键常规键盘上......有不是键盘上的那些按钮之一。
假设你希望每个输入只有一个字符,你可以看看onChangeText
,然后检查是否有文本长度为1,并呼吁重点如果长度确实是1
我以为是这样,我对代码做了一些修改,但它仍然不会工作 –
可以使用对焦方法onChangeText
为杰森说,除了增加maxLength={1}
可以让你跳到下一个输入,而不检查添加什么。 (刚注意到它的已弃用,但仍然这是我如何解决我的问题,并应该做的很好,直到v0.36,并且这link解释如何更新弃用的功能)。
<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()
}}
/>
...
请注意,我用的裁判不建议使用过,但我刚刚复制的代码,因为我可以向你保证,正在当年(希望现在的工作太)。
最后,这种类型的实现的主要问题是,一旦您尝试使用退格删除数字,您的焦点将跳转到下一个数字,导致严重的UX问题。但是,您可以听取退格键输入并执行一些不同的操作,而不是专注于下一个输入。所以我会在这里留下一个link供你进一步调查,如果你选择使用这种类型的实现。
哈克解决先前描述的问题:如果你检查什么在onChangeText
道具进入做任何事情之前,你可以跳转到下一个输入,如果该值是一个数,否则(这是一个退格键),跳回来。 (刚想出这个主意,我没有尝试过。)
我们用不同的方法处理了这种风格的屏幕。
而不是管理4个单独的TextInputs并处理每个人的焦点导航(然后当用户删除一个字符时再回来),我们在屏幕上有一个单独的TextInput,但是不可见(即0px x 0px)宽它具有焦点,maxLength和键盘配置等。
此TextInput从用户处接受输入,但实际上看不到,因为每个字符都是输入的,我们将输入的文本呈现为一系列简单的视图/文本元素,风格与上面的屏幕非常相似。
这种方法对我们来说很合适,不需要管理旁边要重点关注的'下一个'或'以前的'TextInput。
你能提供一些代码吗? – Dlucidone
http://stackoverflow.com/questions/32748718/react-native-how-to-select-the-next-textinput-after-pressing-the-next-keyboar这里是信息。希望这可以帮助。 –
@UjjwalNepal focus()方法已被弃用......,并且在0.40之后,mitch的答案是不可用的http://stackoverflow.com/a/41201939/5809351 –
我想你可以避免在父项中有状态,只要在'componentDidMount'中做第一个输入的焦点,你的'onTextChanged'方法可以看起来像这样'if t == 1 or 2 or 3 then then focus the t + 1'input' – Igorsvee