UI InputField获取焦点时会突出显示其中的所有文本。我想将插入符号移到文本的末尾,以便用户可以继续写入文本。目前我有一个黑客解决方案,它可以工作,但是在文本突出显示时仍然是一个短暂的时刻。这是我的黑客:
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
的保护级别,我收到了一堆错误。
答案 0 :(得分:5)
有一个技巧可以在文本突出显示时禁用短时间。我设法在没有return
功能的情况下重做这个。
1 。获取struct A
{
A() = default;
A(const A&) { puts("copy ctor\n"); }
};
int main()
{
[]{ return *(new A); }(); // prints "copy ctor"
}
的颜色。将其alpha设置为Update()
。
2 。将#1 中的新颜色应用到InputField.selectionColor
。
3 。等待一帧。你必须因为Unity插入符号等待出现一帧。
4 。更改InputField插入位置。
5 。将0
alpha更改回InputField
。
InputField.selectionColor
注意强>:
将插入符号移到文本末尾的最佳方法是使用MoveTextEnd
函数而不是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;
}
}
的错误。
如果您关心这一点,请在上面的代码中将inputField.caretPosition
替换为inputField.caretPosition
。
答案 1 :(得分:0)
好的,我已经弄清楚了。我需要继承原始的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;
}
}
}
答案 2 :(得分: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;
}
}
}