I have an InputField. I want to give it focus via code. No problem. I want to give it focus and already have text in there. Okay, I can do that. Problem is, all the text is highlighted as it is newly selected. Well, I suppose I can use MoveTextEnd(true) to move the caret.
I cannot make this work on the same frame as the text is set / selection of InputField occurs.
If I add a coroutine to wait one frame, it will work.
if (Input.GetKeyDown(KeyCode.Return) || Input.GetKeyDown(KeyCode.KeypadEnter))
{
selected = EventSystem.current.currentSelectedGameObject;
if (!inputField.gameObject.Equals(selected))
{
EventSystem.current.SetSelectedGameObject(inputField.gameObject, null);
inputField.ActivateInputField();
inputField.text = "SOMETEXT";
// this doesn't work same frame???
//inputField.MoveTextEnd(true);
StartCoroutine(WaitForNextFrame());
}
}
WaitForNextFrame just waits 1 frame, then does the inputField.MoveToEnd(true). It works, but is there an better/correct way to do this on the same frame?
You may need to add that code to LateUpdate, simply due to the way that UI is managed. The “Selected” UI element may not be updated till after the frame is rendered.
I created a subclass of InputField, and in its LateUpdate, I call MoveToEnd after base.LateUpdate. The class knows to do this by setting a flag in an override of OnSelect (which also calls base.OnSelect). This will MoveToEnd on the same frame that InputField calls OnFocus > SelectAll internally from LateUpdate
If you look into the InputField code, there is a part where it selects all text when it gains focus. You can block that out if you need to and keep it from selecting all.