Hi, here is a workaround for the GUILayout.PasswordField bug.
It solves the following problems:
- Password appears as clear text on the screen on iOS (bug 441113 reported).
- iOS shows some suggestions and autocorrects while typing the password (!)
I’ve tried some workarounds (see GUILayout.PasswordField() shows whole password when running on iOS before changing characters!?! - Questions & Answers - Unity Discussions), but without any success:
- Workaround solutions that put a Label on top of a PasswordField still autocorrect…
- Workaround solutions that test TouchScreenKeyboard.visible to hide the password briefly display it when the virtual keyboard is sliding…
So my solution (inspired from the first workaround) is to place an invisible button on top of a GUI.Label. The button will manually open a virtual keyboard with the right parameters. Then we fill the GUI.Label with *s.
(This UnityScript code is for Unity 3.5, replace TouchScreenKeyboard by iPhoneKeyboard if you are using Unity 3.4)
private var password : String = "";
private var keyboard : TouchScreenKeyboard = null;
private var oldColor : Color;
private var oldBackgroundColor : Color;
private var r : Rect;
function OnGUI() {
...
if (Application.platform == RuntimePlatform.IPhonePlayer) {
// make the button invisible by setting contentColor and backgroundColor to (0,0,0,0)
oldColor = GUI.contentColor;
GUI.contentColor = new Color(0,0,0,0);
oldBackgroundColor = GUI.backgroundColor;
GUI.backgroundColor = new Color(0,0,0,0);
// here is the invisible button that opens a keyboard on ios
if (GUILayout.Button("", GUILayout.Width(250))) {
keyboard = TouchScreenKeyboard.Open(password, TouchScreenKeyboardType.Default, false, false, true);
}
// update password content
if (keyboard) {
password = keyboard.text;
}
// restore the GUI colors
GUI.contentColor = oldColor;
GUI.backgroundColor = oldBackgroundColor;
// get Rect of last GUI (the button)
r = GUILayoutUtility.GetLastRect();
// draw a Label with * instead of password
GUI.Label(r, (new String("*"[0], password.Length)));
} else {
// use the classic password field when running in the editor or on another platform
password = GUILayout.PasswordField(password, "*"[0], GUILayout.Width(250));
}
}
If you have more than one text or password field in your GUI, you will have to add a check in the code, else the keyboard.text content will be duplicated between the fields… Here is an example for a login/password GUI:
private var login : String = "";
private var password : String = "";
private var keyboard : TouchScreenKeyboard = null;
private var oldColor : Color;
private var oldBackgroundColor : Color;
private var r : Rect;
private var fieldSelected : int = -1;
function OnGUI() {
...
if (Application.platform == RuntimePlatform.IPhonePlayer) {
// make the button invisible by setting contentColor and backgroundColor to (0,0,0,0)
oldColor = GUI.contentColor;
GUI.contentColor = new Color(0,0,0,0);
oldBackgroundColor = GUI.backgroundColor;
GUI.backgroundColor = new Color(0,0,0,0);
// here is the invisible button that opens a keyboard on ios
if (GUILayout.Button("", GUILayout.Width(250))) {
keyboard = TouchScreenKeyboard.Open(login, TouchScreenKeyboardType.Default, false, false, false);
fieldSelected = 0;
}
// update login content
if (keyboard (fieldSelected == 0)) {
login = keyboard.text;
}
// restore the GUI colors
GUI.contentColor = oldColor;
GUI.backgroundColor = oldBackgroundColor;
// get Rect of last GUI (the button)
r = GUILayoutUtility.GetLastRect();
// draw a Label with the login
GUI.Label(r, login);
} else {
// use the classic text field when running in the editor or on another platform
login = GUILayout.TextField(login, GUILayout.Width(250));
}
...
if (Application.platform == RuntimePlatform.IPhonePlayer) {
// make the button invisible by setting contentColor and backgroundColor to (0,0,0,0)
oldColor = GUI.contentColor;
GUI.contentColor = new Color(0,0,0,0);
oldBackgroundColor = GUI.backgroundColor;
GUI.backgroundColor = new Color(0,0,0,0);
// here is the invisible button that opens a keyboard on ios
if (GUILayout.Button("", GUILayout.Width(250))) {
keyboard = TouchScreenKeyboard.Open(password, TouchScreenKeyboardType.Default, false, false, true);
fieldSelected = 1;
}
// update password content
if (keyboard (fieldSelected == 1)) {
password = keyboard.text;
}
// restore the GUI colors
GUI.contentColor = oldColor;
GUI.backgroundColor = oldBackgroundColor;
// get Rect of last GUI (the button)
r = GUILayoutUtility.GetLastRect();
// draw a Label with * instead of password
GUI.Label(r, (new String("*"[0], password.Length)));
} else {
// use the classic password field when running in the editor or on another platform
password = GUILayout.PasswordField(password, "*"[0], GUILayout.Width(250));
}
}