Unity 2022.3.9f1移动端多输入框切换键盘闪烁问题求助
解决Unity 2022.3.9f1移动端InputField切换时软键盘闪烁问题
这个问题的核心是Unity默认的InputField焦点切换逻辑:当旧输入框失去焦点时,会立即触发软键盘隐藏,新输入框激活时再重新唤起键盘,导致闪烁。要解决这个问题,我们需要拦截这一默认行为,让键盘在输入框切换时保持显示。
方法一:自定义InputField扩展
创建一个继承自Unity内置InputField的自定义组件,重写焦点相关方法来控制键盘状态:
using UnityEngine; using UnityEngine.UI; public class PersistentKeyboardInputField : InputField { private static bool _isSwitchingInput = false; // 输入框失去焦点时调用 protected override void OnDeselect(BaseEventData eventData) { // 如果是在切换到另一个输入框,暂时阻止默认的键盘隐藏逻辑 if (_isSwitchingInput) { return; } base.OnDeselect(eventData); } // 输入框获得焦点时调用 public override void OnSelect(BaseEventData eventData) { // 标记当前正在切换输入框 _isSwitchingInput = true; base.OnSelect(eventData); // 延迟一小段时间取消标记,确保旧输入框的OnDeselect已执行完毕 Invoke(nameof(ResetSwitchFlag), 0.1f); } private void ResetSwitchFlag() { _isSwitchingInput = false; } // 处理点击非输入区域的情况,确保键盘能正常隐藏 private void Update() { if (Input.GetMouseButtonDown(0)) { var pointerEventData = new PointerEventData(EventSystem.current); pointerEventData.position = Input.mousePosition; var results = new System.Collections.Generic.List<RaycastResult>(); EventSystem.current.RaycastAll(pointerEventData, results); bool hitInputField = false; foreach (var result in results) { if (result.gameObject.GetComponent<PersistentKeyboardInputField>() != null) { hitInputField = true; break; } } if (!hitInputField && isFocused) { _isSwitchingInput = false; DeactivateInputField(); } } } }
使用时,将场景中原有的InputField组件替换为这个自定义组件即可。
方法二:全局焦点切换监听
如果不想修改InputField组件,可以写一个全局管理脚本,监听EventSystem的焦点变化:
using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.UI; public class InputKeyboardManager : MonoBehaviour { private GameObject _lastSelectedInput; void OnEnable() { EventSystem.current.SetSelectedGameObject += OnSelectedGameObjectChanged; } void OnDisable() { EventSystem.current.SetSelectedGameObject -= OnSelectedGameObjectChanged; } private void OnSelectedGameObjectChanged(GameObject selectedObj) { // 检查新选中的对象是否是InputField if (selectedObj?.GetComponent<InputField>() != null) { // 如果之前选中的也是InputField,阻止旧输入框触发键盘隐藏 if (_lastSelectedInput?.GetComponent<InputField>() != null) { var oldInput = _lastSelectedInput.GetComponent<InputField>(); oldInput.DeactivateInputField(false); // 参数false表示不触发键盘隐藏 } } _lastSelectedInput = selectedObj; } }
将这个脚本挂在场景中的任意持久化GameObject上(比如Canvas),它会自动处理所有InputField的焦点切换,避免键盘闪烁。
注意事项
- 务必在真实移动设备上测试,模拟器的键盘行为可能和真机不一致
- 上述方法同时兼容iOS和Android平台,无需额外区分
- 如果使用第三方输入框插件(比如TMPro的InputField),只需将代码中的
InputField替换为对应的插件类即可
内容的提问来源于stack exchange,提问作者JohnRaja
相关产品推荐
相关产品推荐

