「Unity3D」TMP_InputField关闭虚拟键盘后,再次打开虚拟键盘,此时无法回调onSelect的问题

TMP_InputField可以注册一个onSelect回调函数,在InputField选中的时候回调,但在虚拟键盘手动关闭被返回取消的时候,此时再打开虚拟键盘时,就不会调用onSelect

原因在于,虚拟键盘有三种关闭的操作方式:

  • 第一,是点击虚拟机键盘外部,此时会失去焦点,即LostFocus事件。
  • 第二,是手动点击虚拟键盘的关闭按钮,此时什么事件都不触发,只是虚拟键盘隐藏。
  • 第三,是使用返回按键,此时会导致取消,即Canceled事件。

有趣的是:

  • 第一种,EventSystem.current.currentSelectedGameObject为——null。
  • 第二种,EventSystem.current.currentSelectedGameObject为——InputFieldgameObject
  • 第三种,EventSystem.current.currentSelectedGameObject为——InputFieldgameObject

所以,再次打开虚拟键盘,只有第一种正确回调onSelect——因为,第二种与第三种,InputField依然保持了选中状态,而再次选中同一个对象,不会响应回调,在InputFieldOnPointerDown中可以看到是调用了SetSelectedGameObject

EventSystem.current.SetSelectedGameObject(base.gameObject, eventData);


public void SetSelectedGameObject(GameObject selected, BaseEventData pointer)
{
    if (m_SelectionGuard)
    {
        Debug.LogError("Attempting to select " + selected?.ToString() + "while already selecting an object.");
        return;
    }

    m_SelectionGuard = true;
    if (selected == m_CurrentSelected)
    {
        m_SelectionGuard = false;
        return;
    }

    ExecuteEvents.Execute(m_CurrentSelected, pointer, ExecuteEvents.deselectHandler);
    m_CurrentSelected = selected;
    ExecuteEvents.Execute(m_CurrentSelected, pointer, ExecuteEvents.selectHandler);
    m_SelectionGuard = false;
}

于此同时,对于这三种情况,关闭虚拟键盘时onDeselect的回调如下:

  • 第一种,失去焦点,回调onDeselect,释放选中对象。
  • 第二种,手动关闭,不调用onDeselect,不释放选中对象。
  • 第三种,返回取消,回调onDeselect,不释放选中对象。

是的,这个返回取消,不能正确释放选中状态,还调用了onDeselect——因为这个onDeselect是被直接代码调用的,而不是通过SetSelectedGameObject触发的。

因此,要解决onSelect不调用的问题,就是关闭虚拟键盘时,手动调用EventSystem.current.SetSelectedGameObject(null)——但这会产生另一个小问题:

就是返回取消的时候,onDeselect会调用两次,即:一次来自SetSelectedGameObject,一次来自InputField自己——而失去焦点的情况,会清除选中状态,所以SetSelectedGameObject已经是null,就不会调用onDeselect

那么,解决的方法就是——使用onEndEdit来代替onDeselect

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值