I built a registration form for a mobile game using Unity 5.1. To do that, I use Unity UI components: ScrollRect + Autolayout (Vertical layout) + Text (labels)
The preconditions for my version of this problem:
element
I want to scroll to should be fully visible (with minimal clearance)element
is a direct child of the scrollRect
's contentelement
is already fully visibleThis is what worked best for me (thanks for the other inspirations):
// ScrollRect scrollRect;
// RectTransform element;
// Fully show `element` inside `scrollRect` with at least 25px clearance
scrollArea.EnsureVisibility(element, 25);
Using this extension method:
public static void EnsureVisibility(this ScrollRect scrollRect, RectTransform child, float padding=0)
{
Debug.Assert(child.parent == scrollRect.content,
"EnsureVisibility assumes that 'child' is directly nested in the content of 'scrollRect'");
float viewportHeight = scrollRect.viewport.rect.height;
Vector2 scrollPosition = scrollRect.content.anchoredPosition;
float elementTop = child.anchoredPosition.y;
float elementBottom = elementTop - child.rect.height;
float visibleContentTop = -scrollPosition.y - padding;
float visibleContentBottom = -scrollPosition.y - viewportHeight + padding;
float scrollDelta =
elementTop > visibleContentTop ? visibleContentTop - elementTop :
elementBottom < visibleContentBottom ? visibleContentBottom - elementBottom :
0f;
scrollPosition.y += scrollDelta;
scrollRect.content.anchoredPosition = scrollPosition;
}