React Native中TextInput在键盘弹出过程中失焦的问题解决求助
React Native中TextInput在键盘弹出过程中失焦的问题解决求助
大家好,我最近在开发React Native项目时碰到了一个挺棘手的TextInput焦点问题,想请各位大佬帮忙支支招。
我的场景是:在一个可滚动的页面里有若干输入框,之前遇到点击输入框获取焦点后,滚动页面会触发onBlur导致输入框失焦,但键盘还保持打开状态,而且键盘类型会变回default的问题。后来我通过在滚动时收起键盘的方式解决了一部分,但现在还有个相关的问题没搞定:
当输入框位置比较靠下,我点击它的时候,页面会自动滚动把输入框移到可视区域,但紧接着这个输入框就触发了onBlur失焦了,键盘依然保持打开状态,却没有任何输入框获得焦点。我猜测可能是键盘弹出的瞬间,输入框被键盘短暂遮挡导致暂时不可见,这时候React Native就判定它失去了焦点,等页面滚动调整位置让输入框回到可视区域时,它已经失焦了。
下面是我的相关代码:
自定义TextInput组件代码
({ disabled = false, error = false, errorMessage, icon, iconPressed, inputId, isTextArea = false, label, maskType = "custom", onchangeText, onPressIcon, placeholder, required = false, styleInput, styleView, type = "string", variant = "default", width = "100%", infoToShow = "", ...props }: InputProps, ref: Ref<TextInput | TextInputMask>, //Passar Ref<TextInput> caso o campo não necessite de máscara. Caso precise, passar Ref<TextInputMask> ) => { const [focused, setFocused] = useState(false); const isDefaultSize = !isTextArea; const showIconPressed = false && iconPressed !== undefined; let options: TextInputMaskOptionProp; switch (maskType) { case "credit-card": options = { obfuscated: false, issuer: "visa-or-mastercard", }; break; case "money": options = { unit: "R$", }; break; case "cel-phone": options = { maskType: "BRL", withDDD: true, dddMask: "(99) ", }; break; case "datetime": options = { format: "DD/MM/YYYY" }; } const borderStyle = [ variant === "default" ? { borderWidth: 1, borderRadius: 8, } : { borderBottomWidth: 1, }, { borderColor: error ? Colors.v4RedError : disabled ? Colors.v7GrayDisabled : focused && variant === "bottom-line" ? Colors.primary : Colors.v3GraySubtitle, }, ] as StyleProp<ViewStyle>; useEffect(() => { if (!focused) { hideKeyboard(); } }, [focused]) function textInputByMask() { if (maskType === "custom") { return ( <TextInput {...props} ref={ref as Ref<TextInput>} placeholder={placeholder} cursorColor={Colors.primary} numberOfLines={isDefaultSize ? 1 : 7} multiline={!isDefaultSize} textAlignVertical={isDefaultSize ? "center" : "top"} placeholderTextColor={Colors.v2GrayLargeText} editable={!disabled} onFocus={val => { setFocused(true); }} onBlur={() => { setFocused(false); }} style={[ globalStyles.textBody2, styleInput, { color: Colors.v2GrayLargeText, flex: 1, textAlign: "left" }, ]} /> ); } return ( <TextInputMask ref={ref as Ref<TextInputMask>} {...props} keyboardType="number-pad" placeholder={placeholder} options={options} cursorColor={Colors.primary} numberOfLines={isDefaultSize ? 1 : 7} multiline={!isDefaultSize} textAlignVertical={isDefaultSize ? "center" : "top"} placeholderTextColor={Colors.v2GrayLargeText} editable={!disabled} type={maskType} onFocus={val => { setFocused(true); }} onBlur={() => { setFocused(false) }} style={[ globalStyles.textBody2, styleInput, { color: Colors.v2GrayLargeText, flex: 1, textAlign: "left" }, ]} /> ); } return ( <View style={{ gap: 5 }}> <LabelRequired label={label} color={error ? "v4RedError" : "v1GrayTitle"} required={required} infoToShow={infoToShow} /> <View style={[ allStyles.searchBarContainer, styleView, borderStyle, { width, backgroundColor: disabled ? Colors.v5GrayDivider : Colors.transparent, }, ]}> {textInputByMask()} {icon && ( <TouchableOpacity activeOpacity={onPressIcon ? undefined : 1} onPress={() => { if (onPressIcon) { onPressIcon(); } }}> <IconStyled icon={showIconPressed ? iconPressed.icon : icon.icon} color={error ? "v4RedError" : icon.color} size={icon.size} /> </TouchableOpacity> )} </View> {errorMessage && ( <Subtitle variant="subtitle3" color={error ? "v4RedError" : "v3GraySubtitle"} fontWeight="NotoSans Regular" leftText> {errorMessage} </Subtitle> )} </View> ); },
渲染输入列表的组件代码
export default function EtapaExecucao({ etapa }: EtapaExecucaoProps) { const itensOrdenados = [...etapa.etapaItens].sort((a, b) => a.ordem - b.ordem); // 注:原代码未完整提供,此处仅展示已有的部分
我现在的需求是找到一个能彻底解决这个问题的方案,让输入框在键盘弹出的整个过程中都不会失去焦点,请问各位有没有什么可行的办法或者思路?
内容来源于stack exchange
相关产品推荐
相关产品推荐

