I noticed in RC1 the input field api has changed and I dont like the change. With OnSubmit I got expected behavior → when I pressed return the event was raised. With OnEndEdit the event seems to raise for a number of reasions resulting in unpredictable behavior. For instance I noticed the event being raised from clicking on a text field.
I don’t know whether the newest Unity 4.6 beta has added a way to only submit when return is pressed, but this definitely does not seem to be the case for Unity 5.0 Beta 14.
As such, I wrote a small extension to the InputField component, usable as a replacement for the standard InputField.
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;
using UnityEngine.Events;
public class InputFieldSubmitOnly : InputField {
protected override void Start () {
base.Start();
for (int i = 0; i < this.onEndEdit.GetPersistentEventCount(); ++i) {
int index = i; // Local copy for listener delegate
this.onEndEdit.SetPersistentListenerState(index, UnityEventCallState.Off);
this.onEndEdit.AddListener(delegate(string text) {
if (!EventSystem.current.alreadySelecting) {
((Component)this.onEndEdit.GetPersistentTarget(index)).SendMessage(this.onEndEdit.GetPersistentMethodName(index), text);
}
});
}
}
}
The extension turns off all persistent onEndEdit listeners (those added in the inspector), and adds wrappers for all these that only call the listener methods on submit.
You might also want automatic selection of the next Selectable either right or down from the InputField (I know I did). To achieve this, I use the following code - it first tries finding a Selectable to the right, and if that fails, tries finding one below. The code below goes inside the if-statement above.
Thank you Emma, I was so confused why it is apparently so difficult to get this extremely conventional behaviour (submit-only-on-enter (edited for clarity per Phil’s next comment) ) and your solution works. I am still left feeling like I must simply be misunderstanding something about the UI, though; it’s hard for me to accept that Unity really didn’t provide a way to do this built-in. Surely it is hiding somewhere?
Thanks but your extension doesn’t do anything for me Emma. The event fires off as before. This seems like a pretty big omission to not have a separate event for OnSubmit.
I have found a nice easy fix for this.
Using the onEndEdit function i pointed it to a function i scripted and in that function i just asked if the return key had been pressed
//point the text child object of the input field here
public Text inputText;
string messageToSend;
public void RelayMessage()
{
if(Input.GetButtonDown("Submit")){
messageToSend = inputText.text;
}
}
You don’t have to call the variables the same as me they are just called that in my project and this seemed to work for me so I hope it can work okay for you.
I don’t know if there is now a new way to do this, but I just checked in its onEndEdit handler whether one of the Enter-keys was just clicked:
[SerializeField]
InputField inputField;
private void Start()
{
inputField.onEndEdit.AddListener(val =>
{
if (Input.GetKeyDown(KeyCode.Return) || Input.GetKeyDown(KeyCode.KeypadEnter))
Debug.Log("End edit on enter");
});
}
This seems to work just fine for me. The debug text appears when it has focus and I click one of the enter buttons, but it does not appear if it loses focus because I click elsewhere, which is desired behaviour. I don’t know if there is something criminally wrong about using Input.GetKeyDown outside Update like this.
As this thread shows it’s strange that there is no difference between losing focus and submitting with a key.
Is it not an important difference in some instances where the user may still be intending to edit if focus was lost but when enter is pressed it is a clear submit statement from the user?
I think NGUI had OnSubmit which was just for when return or mobile submit button pressed.
It is depressing that this obvious bug was never fixed in the first place (no other UI system has this problem, only Unity decided to break with convention and make it harder to write UI apps. Almost no-one needs “onLostFocusOrHitEnter” - it’s a mostly useless method. But nearly everyone needs OnSubmit - it’s used all the time, in every app).
But to let it go unfixed for six years (it’s 2020, and this is still broken!) is ridiculous.
Did anyone submit a bug report? Is that what I need to do for someone at Unity to finally fix this bug?
My codebase currently contains a lot of the 1-liner version of @bsivko 's workaround:
public void MySubmittedMethod( InputField field )
{
#if UNITY_UI_TEAM_STILL_HASNT_FIXED_THE_ONSUBMIT_BUG
if( (TouchScreenKeyboard.isSupported && field.touchScreenKeyboard.status == TouchScreenKeyboard.Status.Done)
||(Input.GetKeyDown(KeyCode.Return) || Input.GetKeyDown(KeyCode.KeypadEnter) || Input.GetButtonDown("Submit")) )
#endif
{
// ... process the InputField contents here
}
}