Ok, I’ve dug out the code.
I had two scripts - one which is on the input field and just checks when it becomes active and sets the transform (this app has about 500+ different input fields)
Then I have a second script which is attached to the containing game object (first item below the Canvas).
I used a bit of code I found elsewhere to get a corrected screen corners position: [Unity 4.6 Beta] Rect Transform Position (New UI System) - Questions & Answers - Unity Discussions for the GetScreenRect function, although I inverted the Y output from it. It could be this function is all you need
Ok my code below, it’s not pretty or tidy but seems to work smoothly for me across iPhone 4, iPhone 5, iPad portrait/horiz both retina and non-retina. This is all about making sure the input field is always visible above the keyboard.
This is currently for iOS - not tested on android as yet, hence the #if statements surrounding it so it falls back to not hiding the mobile input on android.
No idea how to format code properly here, sorry!
Apply this to the input field: (change MainContainer to whatever your top item is called)
using UnityEngine;
using System.Collections;
using UnityEngine.UI;
public class InputfieldFocused : MonoBehaviour {
InputfieldSlideScreen slideScreen;
InputField inputField;
void Start () {
slideScreen = GameObject.Find (“MainContainer”).GetComponent();
inputField = transform.GetComponent();
#if UNITY_IOS
inputField.shouldHideMobileInput=true;
#endif
}
#if UNITY_IOS
void Update () {
if (inputField.isFocused)
{
// Input field focused, let the slide screen script know about it.
slideScreen.InputFieldActive = true;
slideScreen.childRectTransform = transform.GetComponent();
}
}
#endif
}
Now, apply this to the MainContainer (or whatever you call it)
using UnityEngine;
using System.Collections;
public class InputfieldSlideScreen : MonoBehaviour {
// Assign canvas here in editor
public Canvas canvas;
// Used internally - set by InputfieldFocused.cs
public bool InputFieldActive = false;
public RectTransform childRectTransform;
#if UNITY_IOS
void LateUpdate () {
if ((InputFieldActive)&&((TouchScreenKeyboard.visible)))
{
transform.GetComponent().anchoredPosition = Vector2.zero;
Vector3[ ] corners = {Vector3.zero,Vector3.zero,Vector3.zero,Vector3.zero};
Rect rect = GetScreenRect(corners,childRectTransform);
float keyboardHeight = TouchScreenKeyboard.area.height;
float heightPercentOfKeyboard = keyboardHeight/Screen.height100f;
float heightPercentOfInput = (Screen.height-(rect.y+rect.height))/Screen.height100f;
if (heightPercentOfKeyboard>heightPercentOfInput)
{
// keyboard covers input field so move screen up to show keyboard
float differenceHeightPercent = heightPercentOfKeyboard - heightPercentOfInput;
float newYPos = transform.GetComponent().rect.height /100f*differenceHeightPercent;
Vector2 newAnchorPosition = Vector2.zero;
newAnchorPosition.y = newYPos;
transform.GetComponent().anchoredPosition = newAnchorPosition;
} else {
// Keyboard top is below the position of the input field, so leave screen anchored at zero
transform.GetComponent().anchoredPosition = Vector2.zero;
}
} else {
// No focus or touchscreen invisible, set screen anchor to zero
transform.GetComponent().anchoredPosition = Vector2.zero;
}
InputFieldActive = false;
}
public Rect GetScreenRect(Vector3[ ] corners,RectTransform rectTransform) {
rectTransform.GetWorldCorners(corners);
float xMin = float.PositiveInfinity, xMax = float.NegativeInfinity, yMin = float.PositiveInfinity, yMax = float.NegativeInfinity;
for (int i = 0; i < 4; ++i) {
// For Canvas mode Screen Space - Overlay there is no Camera; best solution I’ve found
// is to use RectTransformUtility.WorldToScreenPoint) with a null camera.
Vector3 screenCoord = RectTransformUtility.WorldToScreenPoint(null, corners*);*
if (screenCoord.x < xMin) xMin = screenCoord.x;
if (screenCoord.x > xMax) xMax = screenCoord.x;
if (screenCoord.y < yMin) yMin = screenCoord.y;
if (screenCoord.y > yMax) yMax = screenCoord.y;
corners = screenCoord;
}
Rect result = new Rect(xMin, Screen.height-yMin - (yMax - yMin), xMax - xMin, yMax - yMin);
return result;
}
#endif
}