当UI.InputField获得焦点时,如何禁用SelectAll()文本?

4
当 UI InputField 获得焦点时,所有文本都会被突出显示。我想把插入符号移动到文本的末尾,以便用户可以继续输入文本。目前,我有一个 hack 解决方案,它能够正常工作,但在文本被突出显示时仍然存在短暂的时刻。这是我的 hack:
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;

public class TextFieldBehaviour : MonoBehaviour, ISelectHandler
{
    private InputField inputField;
    private bool isCaretPositionReset = false;

    void Start()
    {
        inputField = gameObject.GetComponent<InputField>();
    }

    public void OnSelect (BaseEventData eventData) 
    {
        isCaretPositionReset = false;
    }

    void Update()
    {
        if(inputField.isFocused == true && isCaretPositionReset == false)
        {
            inputField.caretPosition = inputField.text.Length;
            isCaretPositionReset = true;
        }
    }
}

我也在查看InputField的源代码。但是我在创建没有SelectAll()函数的自定义输入框时遇到了麻烦。由于UnityEngine.UI.SetPropertyUtility的保护级别,我得到了一堆错误。
3个回答

6

有一种技巧可以禁用文本被高亮显示的短暂时刻。我成功地重新实现了这一点,而不需要使用Update()函数。

1、获取InputField.selectionColor的颜色。将其alpha设置为0

2、将步骤#1中的新颜色应用到InputField上。

3、等待一帧。必须这样做,因为Unity光标需要等待一帧才能出现。

4、更改InputField的光标位置。

5、将InputField.selectionColor的alpha值改回1

public class TextFieldBehaviour : MonoBehaviour, ISelectHandler
{
    private InputField inputField;
    private bool isCaretPositionReset = false;

    void Start()
    {
        inputField = gameObject.GetComponent<InputField>();
    }

    public void OnSelect(BaseEventData eventData)
    {
        StartCoroutine(disableHighlight());
    }

    IEnumerator disableHighlight()
    {
        Debug.Log("Selected!");

        //Get original selection color
        Color originalTextColor = inputField.selectionColor;
        //Remove alpha
        originalTextColor.a = 0f;

        //Apply new selection color without alpha
        inputField.selectionColor = originalTextColor;

        //Wait one Frame(MUST DO THIS!)
        yield return null;

        //Change the caret pos to the end of the text
        inputField.caretPosition = inputField.text.Length;

        //Return alpha
        originalTextColor.a = 1f;

        //Apply new selection color with alpha
        inputField.selectionColor = originalTextColor;
    }
}

注意:

将光标移动到文本末尾的最佳方法是使用MoveTextEnd函数,而不是inputField.caretPosition。如果您的文本很长,则会注意到inputField.caretPosition存在错误。

如果您关心此问题,请在上面的代码中将inputField.caretPosition = inputField.text.Length;替换为inputField.MoveTextEnd(false);


谢谢你的解决方案。我已经成功地想出了一个可行的解决方案。如果你有时间,我希望能得到一些关于它的反馈。 - rjth
当然,我会看一下。 - Programmer
嗨@程序员。顺便说一句,代码写得很好!在我的台式机上完美运行!我试着在平板电脑上测试了这个应用,但整段文字仍然会被高亮显示 :/ 你知道如何让你的代码也适用于移动设备吗? - Lloyd
抱歉,有人能帮忙吗? :/ - Lloyd

1

好的,我已经弄清楚了。我需要从原始InputField继承并使用必要的功能进行扩展。这是可用的脚本:

using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;

public class CustomInputField : InputField
{
    new public bool Focused = false;
    new public bool Deactivated = false;

    new public void ActivateInputField()
    {
        Focused = true;
        base.ActivateInputField();
    }

    public override void OnDeselect(BaseEventData eventData)
    {
        Deactivated = true;
        DeactivateInputField();
        base.OnDeselect(eventData);
    }

    public override void OnPointerClick(PointerEventData eventData)
    {
        if(Deactivated)
        {
            MoveTextEnd(true);
            Deactivated = false;
        }
        base.OnPointerClick(eventData);
    }

    protected override void LateUpdate()
    {
        base.LateUpdate();
        if(Focused)
        {
            MoveTextEnd(true);
            Focused = false;
        }
    }
}

1
有趣的解决方案。不过还是有一些问题。1. 不应该重写非虚函数(ActivateInputField)。 2. 我已经在Unity 5.5上尝试过,但是它并没有起作用。你甚至不能单击InputField。 - Programmer
感谢回复。虽然在Unity 5.5.0f3上可以工作,但是遮蔽或隐藏非虚函数从来都不是一个好主意。我可能稍后会尝试一种略微不同的方法。 - rjth
1
嗨,我刚意识到你的脚本移除了我的InputField的Text组件。我重新附加它并且能够点击它。代码并没有解决这个问题。文字被高亮显示的短暂时刻仍然存在。第一次单击它时,问题不存在。其他时间则有问题。祝编码愉快! - Programmer
好的,我现在会继续使用你的解决方案。它更加优雅。谢谢! - rjth

0
感谢您提供的解决方案,它们真的很有帮助。我认为对您的方法进行以下适应可以消除选择高亮显示的时间分数。在我的用例中,它有效,但我还没有进行充分的测试。 (实际上,这是用于略微不同的用例,在该用例中,您既可以使用鼠标选择,也可以使用事件系统进行选择,但将其保留以防对正在寻找此类问题的人有所帮助,就像我一样)。
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;

public class SourceCodeTextStopFocusSelection : InputField
{
    bool justSelected = false;
    int selectedPosition;

    public override void OnSelect(BaseEventData eventData)
    {
        base.OnSelect(eventData);
        if (eventData is PointerEventData)
        {
            Vector2 mousePos;
            PointerEventData pointerData = eventData as PointerEventData;
            RectTransformUtility.ScreenPointToLocalPointInRectangle(textComponent.rectTransform, pointerData.position, pointerData.pressEventCamera, out mousePos);
            selectedPosition = GetCharacterIndexFromPosition(mousePos);
        }
        else
        {
            selectedPosition = text.Length;
        }
        justSelected = true;
    }

    protected override void LateUpdate()
    {
        base.LateUpdate();
        if (justSelected)
        {
            caretPosition = selectedPosition;

            ForceLabelUpdate();
            justSelected = false;
        }
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接