「Unity3D」TextMeshPro的TMP_InputField复制粘贴时,onValueChanged多次回调的问题解决

TextMeshProTMP_InputField注册onValueChanged回调之后,如果使用复制粘贴,则onValueChanged会在每个字符上调用。

通过源码可见:

case KeyCode.V:
{
    if (ctrlOnly)
    {
        Append(clipboard);
        return EditState.Continue;
    }
    break;
}


//-------------------------------------------------


/// <summary>
/// Append the specified text to the end of the current.
/// </summary>
protected virtual void Append(string input)
{
    if (m_ReadOnly)
        return;

    if (InPlaceEditing() == false)
        return;

    for (int i = 0, imax = input.Length; i < imax; ++i)
    {
        char c = input[i];

        if (c >= ' ' || c == '\t' || c == '\r' || c == '\n')
        {
            Append(c);
        }
    }
}


解决办法,是继承TMP_InputField,然后重写Append(string)方法。

/// <summary>
/// Appends string (clipboard) to the text and just calls the onValueChanged once.
/// The original onValueChanged is called per char, not once per string.
/// </summary>
protected override void Append(string input)
{
    if (this.onValueChanged != null)
    {
        var onChangeEvent   = this.onValueChanged;
        this.onValueChanged = null;
        base.Append(input);
        this.onValueChanged = onChangeEvent;

        // update the lineCount for onValueChanged
        this.UpdateLabel();
        this.onValueChanged.Invoke(this.text);
    }
    else    
    {
        base.Append(input);
    }
}

这里有两个问题,值得指出:

  • 重写方式是,禁用onValueChanged,调用父类Append(string),再恢复onValueChanged
  • 调用onValueChanged之前,需要UpdateLabel(),因为粘帖大段文本,会触发行数的改变,如果不调用更新,这在onValueChanged中无法正确检测到,lineCount的改变。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值