文本输入忽略了 React Native 上的双击(句点)



我有TextInput组件,每当用户键入时它都会更改状态,但我意识到由于TextInput的值使用this.state.text作为值,双击空格不会在iOS上产生句点。

有没有解决方法,所以双击空间仍然可以在ios上产生周期?

onChange =(text) => {
this.setState({text});
}


<TextInput
onChangeText={this.onChange}
onSubmitEditing={this.onSubmit}
value={this.state.text}
autoCapitalize="sentences"
blurOnSubmit={false}
editable={true}
/>
import React, { Component } from 'react';
import { AppRegistry, TouchableOpacity, View, TextInput } from 'react-native';
class UselessTextInput extends Component {
constructor(props) {
super(props)
this.state = {
lastPress: 0
}
}
onPress = () => {
var delta = new Date().getTime() - this.state.lastPress;
if (delta < 200) {
alert("DOUBLE TAP")
// double tap happend
}
this.setState({
lastPress: new Date().getTime()
})
}
render() {
return (
<TouchableOpacity onPress={this.onPress}>
<TextInput
pointerEvents="none"
/>
</TouchableOpacity>
);
}
}
export default class UselessTextInputMultiline extends Component {
constructor(props) {
super(props);
this.state = {
text: 'Useless Multiline Placeholder',
};
}
// If you type something in the text box that is a color, the background will change to that
// color.
render() {
return (
<View style={{
backgroundColor: this.state.text,
borderBottomColor: '#000000',
borderBottomWidth: 1
}}
>
<UselessTextInput
multiline={true}
numberOfLines={4}
onChangeText={(text) => this.setState({ text })}
value={this.state.text}
/>
</View>
);
}
}
// skip these lines if using Create React Native App
AppRegistry.registerComponent(
'AwesomeProject',
() => UselessTextInputMultiline
);

您可以根据您的要求对其进行编辑,我已经在 react 本机文档网站上尝试过它并且它有效。

onChange 事件在文本输入字段上会导致问题,例如键盘快捷键(双击空格以创建句点 (.((,因为状态是每次击键更改并且键盘无法捕获双倍空格。

因此,我不是将值存储在状态中,而是在 SubmitEdit 上捕获它,捕获最终值。

<TextInput
onSubmitEditing={this.onSubmit}
value={this.state.text}
placeholder="Say Something.."
blurOnSubmit={false}
editable={true}
/>

然后我们创建一个提交函数,对文本执行某些操作并清除字段。

onSubmit = (e) => {
const text = e.nativeEvent.text;
this.setState({text}, () => { // <- Important Callback after setstate
//Whatever U want to do with the data here.
this.setState({text: ''}) // clear the field (this must be in the callback)
})
}

我们将 this.state.text 设置为文本,以便我们可以在之后将其设置回 '' 回电。如果不执行此步骤,则状态不会更改,并且 组件不会刷新空字段。

我意识到使用这种方法,所有键盘功能都将正常工作,包括句点(.(的双倍行距,甚至复制和粘贴值,而无需使用 setState。

更新:启用多行解决方案。

以上适用于单行,对于我们不使用 onSubmitEditing 而是使用按钮的多行,我们需要在文本输入中添加一个 ref。

<TextInput
ref={input => { this.textMessage = input }} //Important.
//onSubmitEditing={this.onSubmit} //Remove so we can use newline
value={this.state.text}
placeholder="Say Something.."
blurOnSubmit={false}
editable={true}
multiline={true}
/>

创建执行提交的按钮

<Button onPress={this.onSubmit} 
title="Send"
/>

还有一种通过引用onSubmit函数获取值的另一种方法

onSubmit = () => {
const text = this.textMessage._lastNativeText.trim(); //Remember the ref from textInput?
this.setState({text}, () => {
//Do whatever u want with the text here
this.setState({text: ''}) //clear the field
this.textMessage._lastNativeText = ''; //you need to clear this too
})

注意:如果您未将this.textMessage._lastNativeText设置为空,则 当您单击"发送"时,将继续提交以前的值 按钮,即使文本输入在视觉上看起来是空的。

这与苹果的行为非常接近。如果有人能找到一种与苹果功能不相等的方法,请告诉我。

import {useRef} from "react";
const useTextInputReplacer = () => {
const lastText = useRef<string>("");
const lastSpaceEnteredAt = useRef<number>();
const periodReplaceDisabled = useRef<boolean>(true);
const isLastCharacterAlphaNumeric = str => str[str.length - 1].match(/[a-zA-Z0-9]/);
return (_text) => {
if (lastText.current && _text.length) {
if (lastText.current.length < _text.length) {  // add case
if (_text[_text.length - 1] === " " && !periodReplaceDisabled.current) {
const now = new Date().getTime();
if (lastSpaceEnteredAt.current && (now - lastSpaceEnteredAt.current) < 300) {
lastSpaceEnteredAt.current = undefined;
_text = _text.replace(/s{2}$/, ". ");
periodReplaceDisabled.current = true;
} else if (!periodReplaceDisabled.current && isLastCharacterAlphaNumeric(lastText.current)) {
lastSpaceEnteredAt.current = now;
}
} else {
periodReplaceDisabled.current = !isLastCharacterAlphaNumeric(lastText.current);
}
} else if (lastText.current.length > _text.length) { // deletion case
periodReplaceDisabled.current = lastText.current[lastText.current.length - 1] === "." || !isLastCharacterAlphaNumeric(_text);
}
}
lastText.current = _text;
return _text;
};
};

然后在您的组件中


const textInputReplacer = useTextInputReplacer();
<Input 
onChangeText={text => updateText(textInputReplacer(text))}
/>

最新更新