You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React Native(Expo)自定义按钮隐藏键盘后TextInput焦点异常求助

React Native(Expo)自定义键盘关闭按钮焦点问题解决方案

问题现象

使用硬件Esc键关闭键盘时,TextInput会完全失去焦点,后续滚动内容松开手指后键盘保持收起(符合预期);但点击调用Keyboard.dismiss()的自定义工具栏按钮时,键盘虽收起,TextInput仍保留焦点,导致每次滚动松开手指后键盘都会重新弹出。

解决方案

核心是在关闭键盘的同时,主动让所有TextInput失去焦点,模拟硬件Esc键的完整行为。具体步骤如下:

1. 引入useRef钩子并创建输入框引用

在组件顶部导入useRef,并创建存储两个TextInput实例的引用:

import { useRef, useEffect, useState } from "react";

export default function WriteScreen() {
  // ... 原有代码
  const titleInputRef = useRef(null);
  const contentInputRef = useRef(null);
  // ... 原有代码
}

2. 给每个TextInput绑定ref属性

修改UI布局中的两个TextInput,分别绑定对应的引用:

<TextInput
  ref={titleInputRef}
  style={styles.title}
  placeholder="제목"
  placeholderTextColor="#999"
/>

<TextInput
  ref={contentInputRef}
  style={styles.content}
  placeholder="내용"
  placeholderTextColor="#999"
  multiline
  textAlignVertical="top"
/>

3. 更新dismissKeyboard函数

修改关闭键盘的逻辑,先让所有输入框失去焦点,再调用Keyboard.dismiss():

const dismissKeyboard = () => {
  // 让标题输入框失焦
  titleInputRef.current?.blur();
  // 让内容输入框失焦
  contentInputRef.current?.blur();
  // 收起键盘
  Keyboard.dismiss();
};

完整修改后的组件代码

import { MaterialIcons } from "@expo/vector-icons";
import { useHeaderHeight } from "expo-router/react-navigation";
import { useRef, useEffect, useState } from "react";
import {
  Keyboard,
  KeyboardAvoidingView,
  Platform,
  Pressable,
  StyleSheet,
  TextInput,
  View,
} from "react-native";

export default function WriteScreen() {
  const headerHeight = useHeaderHeight();
  const [isKeyboardVisible, setIsKeyboardVisible] = useState(false);
  const titleInputRef = useRef(null);
  const contentInputRef = useRef(null);

  useEffect(() => {
    const showEvent =
      Platform.OS === "ios" ? "keyboardWillShow" : "keyboardDidShow";
    const hideEvent =
      Platform.OS === "ios" ? "keyboardWillHide" : "keyboardDidHide";

    const show = Keyboard.addListener(showEvent, () =>
      setIsKeyboardVisible(true),
    );
    const hide = Keyboard.addListener(hideEvent, () =>
      setIsKeyboardVisible(false),
    );
    return () => {
      show.remove();
      hide.remove();
    };
  }, []);

  const dismissKeyboard = () => {
    titleInputRef.current?.blur();
    contentInputRef.current?.blur();
    Keyboard.dismiss();
  };

  return (
    <KeyboardAvoidingView
      style={styles.container}
      behavior={Platform.OS === "ios" ? "padding" : "height"}
      keyboardVerticalOffset={headerHeight}
    >
      <TextInput
        ref={titleInputRef}
        style={styles.title}
        placeholder="제목"
        placeholderTextColor="#999"
      />

      <TextInput
        ref={contentInputRef}
        style={styles.content}
        placeholder="내용"
        placeholderTextColor="#999"
        multiline
        textAlignVertical="top"
      />

      <View style={styles.toolbar}>
        {isKeyboardVisible ? (
          <Pressable
            style={styles.keyboardDismissButton}
            onPress={dismissKeyboard}
            hitSlop={8}
            accessibilityRole="button"
          >
            <MaterialIcons name="keyboard-hide" size={22} />
          </Pressable>
        ) : null}
      </View>
    </KeyboardAvoidingView>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    paddingHorizontal: 16,
    backgroundColor: "#fff",
  },
  flex: {
    flex: 1,
  },
  scrollContent: {
    flexGrow: 1,
  },
  title: {
    fontSize: 20,
    fontWeight: "bold",
    paddingVertical: 12,
  },
  content: {
    flexGrow: 1,
    fontSize: 16,
    textAlignVertical: "top",
  },
  toolbar: {
    height: 48,
    flexDirection: "row",
    justifyContent: "flex-end",
    alignItems: "center",
    borderTopWidth: StyleSheet.hairlineWidth,
    borderTopColor: "#ddd",
  },
  toolbarButton: {
    padding: 8,
  },
  keyboardDismissButton: {
    padding: 4,
    borderRadius: 10,
    alignItems: "center",
    justifyContent: "center",
  },
});

原理说明

Keyboard.dismiss()仅负责收起系统键盘,但不会改变TextInput的焦点状态。而硬件Esc键会同时触发键盘收起和输入框失焦两个动作。通过手动调用blur()方法,我们让自定义按钮的行为和Esc键完全一致,从而避免滚动时键盘意外弹出的问题。

内容的提问来源于stack exchange,提问作者wjsyuwls

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.04 14:14:49