Я делюсь своим компонентом ниже, пожалуйста, дайте мне знать, какая модификация может помочь достичь моей цели
Код: Выделить всё
import React, { useEffect, useRef, useState } from 'react';
import {
NativeSyntheticEvent,
Platform,
StyleSheet,
TextInput,
TextInputKeyPressEventData,
View,
ViewStyle,
} from 'react-native';
import colors from 'res/colors';
import fonts from 'res/fonts';
import { getScaledNumber } from 'library/Utils';
import { Clipboard } from 'react-native';
interface CombinedOtpInputProps {
inputCount?: number;
onOtpChange: (otp: string) => void;
containerStyle?: ViewStyle;
autoFocus?: boolean;
}
const CombinedOtpInput: React.FC = ({
inputCount = 6,
onOtpChange,
containerStyle,
autoFocus = false,
}) => {
const [otp, setOtp] = useState(Array(inputCount).fill(''));
const [focusedInput, setFocusedInput] = useState(0);
const inputsRef = useRef([]);
useEffect(() => {
if (autoFocus && inputsRef.current[0]) {
inputsRef.current[0]?.focus();
}
}, [autoFocus]);
const checkClipboardForOTP = async () => {
const clipboardContent = await Clipboard.getString();
if (clipboardContent) {
const otpRegex = /\b\d{4,6}\b/;
const otpMatch = clipboardContent.match(otpRegex);
if (otpMatch) {
const otpArray = otpMatch[0].split('');
setOtp(otpArray);
Clipboard.setString('');
const lastFilledIndex = Math.min(otpArray.length, inputCount) - 1;
inputsRef.current[lastFilledIndex]?.focus();
}
}
};
const handleTextChange = (text: string, index: number) => {
if (Platform.OS === 'android' && text.length === 1) {
checkClipboardForOTP();
}
if (/^\d*$/.test(text)) {
const newOtp = [...otp];
newOtp[index] = text;
setOtp(newOtp);
onOtpChange(newOtp.join(''));
// Move focus to the next input if current input is not empty
if (text && index < inputCount - 1) {
inputsRef.current[index + 1]?.focus();
setFocusedInput(index + 1);
}
}
};
const handleKeyPress = (e: NativeSyntheticEvent, index: number) => {
if (e.nativeEvent.key === 'Backspace' && otp[index] === '' && index > 0) {
inputsRef.current[index - 1]?.focus();
setFocusedInput(index - 1);
}
};
return (
{Array(inputCount)
.fill(0)
.map((_, i) => {
let inputContainerStyle = {
borderWidth: 1,
borderColor: colors.gainsboroGray,
};
let inputStyle = { ...styles.textInput };
const value = otp[i];
if (focusedInput === i && (value?.length === 0 || value === undefined)) {
inputStyle = { ...inputStyle, fontSize: 16, fontFamily: fonts.ssd_thin };
} else {
if (value?.length > 0) {
inputStyle = { ...inputStyle, backgroundColor: colors.lightSilver };
inputContainerStyle = {
...inputContainerStyle,
borderColor: colors.lightSilver,
borderWidth: 1,
};
} else {
inputStyle = { ...inputStyle, backgroundColor: colors.white };
}
}
return (
(inputsRef.current[i] = ref)}
style={inputStyle}
value={otp[i]}
onChangeText={(text) => handleTextChange(text, i)}
onKeyPress={(e) => handleKeyPress(e, i)}
keyboardType='numeric'
maxLength={1}
selectionColor={colors.primaryGrey}
autoFocus={autoFocus && i === 0}
textContentType='oneTimeCode'
/>
);
})}
);
};
const styles = StyleSheet.create({
container: {
flexDirection: 'row',
justifyContent: 'space-between',
width: '100%',
alignSelf: 'center',
},
inputContainer: {
borderWidth: 1,
borderColor: colors.gainsboroGray,
borderRadius: getScaledNumber(8),
width: 40,
height: 45,
overflow: 'hidden',
},
textInput: {
height: 45,
fontFamily: fonts.ssd_semiBold,
fontSize: getScaledNumber(24),
textAlign: 'center',
color: colors.primaryGrey,
backgroundColor: colors.white,
padding: 0,
},
});
export default CombinedOtpInput;
Любая помощь будет очень признательна.
Заранее спасибо.
Я хочу добиться функциональности автозаполнения OTP, в частности, в iOS, так как в Android он работает довольно хорошо.
Я пробовал использовать множество библиотек и пытался изменить библиотечный код, но в конце концов я не достиг ожидаемого поведения пользовательского интерфейса.
Поэтому я создал общий компонент машинописного текста React Native для обработки автозаполнения, но в котором он заполняет значение только для первого поля ввода, а не для остальных. .
Подробнее здесь: https://stackoverflow.com/questions/785 ... act-native