Move cursor to end of text

Hey there Stefan and team, question for you. We have the use case of programatically selecting a TMP_InputField component and setting the cursor at the end so somebody can start typing from the end.

Both Select() and ActivateInputField() successfully give focus to the input field but select all of the text. Setting caretPosition after that doesn’t seem to do anything. Tried both the MoveTextEnd() and MoveToEndOfLine() methods with no success either.

1 Like

Turns out there’s an option in “Control Settings” on the input field component for ‘OnFocus - Select All’, just had to un-check that. :smile:

1 Like

Well, I still haven’t solved the “move cursor to end of text” issue, but I solved the “it’s highlighting all text when selected” problem.

inputField.MoveToEndOfLine(false, false); works for me.
You may try to execute it with a delay. E.g. in a coroutine after a yield return new WaitForEndOfFrame(); or in LateUpdate.

7 Likes

Doesn’t do nothing for me :frowning:

This function should be working as intended as I tested it last night again.

Please provide the full scripts where you are trying to use this function. See if you can produce a simple repro script for me to use for testing.

I have fixed this the other day. A friend of mine provided an alternative.

1 Like

Kinda old, but LateUpdate worked for me, thanks !

1 Like

Use inputField.MoveToEndOfLine(false, true) if you wanna go to the end of all of the text.

I got the opposite problem - I would like to keep all text selected but still move the cursor to the end of the input field. Select() and ActivateInputField() work as intended in that case, but MoveToEndOfLine() deselects all text again no matter which parameters I pass to it.

    private async void PlaceCursor() {
        inputField.Select();
        inputField.ActivateInputField();
        await System.Threading.Tasks.Task.Delay(10);
        inputField.MoveToEndOfLine(shift: true, ctrl: false);
    }

Increasing the delay makes it possible to observe the behavior rather well. All text is selected until the cursor is placed.

7675618--959050--input_deselected_text.gif

I bumped into this old thread while trying to get my text input to work as intended. (With Unity 2021.1.25)

The problem is that I try to activate and set the text position in the same tick. When I call MoveTextEnd after activating the text input object I can see in the debugger that text is correct and text.length is non-zero. However, as I don’t have rich text editing enabled, position is determined by this, which results in -1: “int position = m_TextComponent.textInfo.characterCount - 1”

If I set rich text editing true (which I definitely don’t want to do), the position setting is taken from text.length which works and makes the caret be at the end. I fixed this with an ugly hack of setting the position again in the next tick.

As a sidenote, I find it confusing the m_isRichTextEditingAllowed part of the if is simpler than the non-rich-text version but maybe there is a good reason for that… This is the function as shown in my debugger:

        public void MoveTextEnd(bool shift)
        {
            if (m_isRichTextEditingAllowed)
            {
                int position = text.Length;
                if (shift)
                {
                    stringSelectPositionInternal = position;
                }
                else
                {
                    stringPositionInternal = position;
                    stringSelectPositionInternal = stringPositionInternal;
                }
            }
            else
            {
                int position = m_TextComponent.textInfo.characterCount - 1;
                if (shift)
                {
                    caretSelectPositionInternal = position;
                    stringSelectPositionInternal = GetStringIndexFromCaretPosition(position);
                }
                else
                {
                    caretPositionInternal = caretSelectPositionInternal = position;
                    stringSelectPositionInternal = stringPositionInternal = GetStringIndexFromCaretPosition(position);
                }
            }
            UpdateLabel();
        }
2 Likes