Dynamically Selecting Text

Hello,

I was wondering if there was a way to select/highlight a specific set of text from a Unity InputField.

I’ve been able to have it select from the current caret position to the start or end with: https://docs.unity3d.com/ScriptReference/UI.InputField.MoveTextStart.html and https://docs.unity3d.com/ScriptReference/UI.InputField.MoveTextEnd.html , respectively, however I haven’t been able to select a specific subset of text.

I attempted to manually set the properties for: selectionAnchorPosition, selectionFocusPosition, and or caretPosition, however beyond being able to update the caret position, the selection highlights don’t seem to update. I also tried to call Rebuild() https://docs.unity3d.com/ScriptReference/UI.InputField.Rebuild.html to see if it needed an explicit call after updating the selection anchors and focus, without success.

Any advice is appreciated.

Another late answer, but this appears in the top results on google. I went through exactly the painful process that the OP went through with the same results.
@jackbreurkes 's answer did not work for me, but I did finally manage to figure it out.

The key was a function called ForceLabelUpdate. This function does exactly what I expected the Rebuild function to do. Not sure how this affects performance, but I assume you want to call this function only when absolutely necessary.

Here is my code:

using UnityEngine;
using UnityEngine.UI;

public class InputFieldSelectionTest : Monobehaviour {

    private InputField inputField;
    public int caretPos = 0;
    public int selectionPos = 0;

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

    void Update(){
        //For testing only, caret and highlighting will not show if not focused
        if (!inputField.isFocused) {
            inputField.ActivateInputField();
        }
        if(inputField.caretPosition != caretPos || caretPos != selectionPos){
              inputField.caretPosition = caretPos;
              inputField.selectionAnchorPosition = caretPos;
              inputField.selectionFocusPosition = selectionPos;
              inputField.ForceLabelUpdate();
        }
    }
}

The above code results in the behavior I expect: when the selection position is the same as the caret position, a caret appears and blinks. When the selection position and the caret position are different, the text between the two positions is highlighted.

Note: If you call ForceLabelUpdate every frame the cursor will never blink.

I found this solution because I realized that I could force the selected text to behave as expected if I changed the Selection Color property of my input field in the inspector. I then tried setting the Selection Color in Update, but that didn’t do anything. This led me to the OnValidate function in the InputField source code, which called the protected function UpdateLabel.

Late answer but could be useful to people who come across this in future. I found that using OnSelect to trigger a flag, then checking if the flag was == true in LateUpdate() (it didn’t work in regular Update), then setting inputField.selectionAnchorPosition and inputField.selectionFocusPosition through the check in LateUpdate() allowed me to set the start and end positions to anything I wanted. Here is my code:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;

public class InputHighlighter : MonoBehaviour, ISelectHandler {

	private InputField inputField;
	private bool moveCaret = false;


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

	void LateUpdate () {
		if (moveCaret) {
			inputField.selectionAnchorPosition = 0;
			inputField.selectionFocusPosition = inputField.text.Length;
			moveCaret = false;
		}
	}

	public void OnSelect(BaseEventData eventData) {
		moveCaret = true;
	}
}

Thanks @AaronIsTheBest :
in my case I was able to actually select text using selectionAnchorPosition and selectionFocusPosition, but the inputField was not highlighted without calling the ForceLabelUpdate()