【问题标题】:How to disable SelectAll() text of UI.InputField when it gets focus?获得焦点时如何禁用 UI.InputField 的 SelectAll() 文本?
【发布时间】:2017-01-05 12:08:23
【问题描述】:

UI InputField 获得焦点时会突出显示里面的所有文本。我想将插入符号移到文本的末尾,以便用户可以继续在其中编写文本。目前我有一个 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 的 source code。但是我很难在没有 SelectAll() 函数的情况下创建自定义的。由于UnityEngine.UI.SetPropertyUtility 的保护级别,我遇到了一堆错误。

【问题讨论】:

    标签: c# unity3d


    【解决方案1】:

    有一个技巧可以禁用突出显示文本的短暂时刻。我设法在没有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);。

    【讨论】:

    • 感谢您的解决方案。我自己设法想出了一个可行的解决方案。如果您有时间,我将不胜感激。
    • 好的,我去看看。
    • 嗨@programmer。顺便说一句,代码很棒!在PC上为我工作!我在平板电脑上测试了该应用程序,但整个文本仍然突出显示:/你知道如何让你的代码也适用于移动设备吗?
    • 对不起,有人可以帮忙吗? ://
    【解决方案2】:

    好的,我想通了。我需要从原始 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.你应该not覆盖一个非虚函数(ActivateInputField)。 2.我用 Unity 5.5 试过这个,但它不起作用。它根本不起作用。你甚至不能点击 InputField。
    • 感谢您的回复。它适用于我的 Unity 5.5.0f3。是的,隐藏或隐藏非虚拟功能绝不是一个好主意。稍后我可能会尝试一些不同的方法。
    • 嗨,我刚刚意识到您的脚本删除了我的 InputField 的文本组件。我把它贴回去并且能够点击它。代码不能解决问题。突出显示文本的那一瞬间仍然在那里。第一次单击它时,问题不存在。其他时候,问题就在那里。编码愉快!
    • 好吧,我现在会坚持使用您的解决方案。它更优雅。谢谢!
    【解决方案3】:

    感谢您的解决方案,它们真的很有帮助,我认为您的方法的以下调整消除了突出显示选择的时间部分。它适用于我的用例,尚未对其进行可靠测试。 (实际上,这是一个稍微不同的用例,您既可以使用鼠标进行选择,也可以使用事件系统,但会留下对寻找这个的人有帮助的情况,就像我一样)。

    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;
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-04-02
      • 2010-09-14
      • 1970-01-01
      • 1970-01-01
      • 2012-09-22
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多