How to scroll to a specific element in ScrollRect

2019-04-05 05:23发布

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) + Input Field. This part works fine.

But, when keyboard is opened, the selected field is under keyboard. Is there a way to programmatically scroll the form to bring the selected field into view?

I have tried using ScrollRect.verticalNormalizedPosition and it works fine to scroll some, however I am not able to make selected field appear where I want.

Thanks for your help !

4条回答
Viruses.
2楼-- · 2019-04-05 05:38

Yes,this is possible using coding to scroll vertically, please try this code :

//Set Scrollbar Value - For Displaying last message of content
Canvas.ForceUpdateCanvases ();
verticleScrollbar.value = 0f;
Canvas.ForceUpdateCanvases ();

This code working fine for me ,when i developed chat functionality.

查看更多
该账号已被封号
3楼-- · 2019-04-05 05:40

I am going to give you a code snippet of mine because i feel like being helpful. Hope this helps!

protected ScrollRect scrollRect;
protected RectTransform contentPanel;

public void SnapTo(RectTransform target)
    {
        Canvas.ForceUpdateCanvases();

        contentPanel.anchoredPosition =
            (Vector2)scrollRect.transform.InverseTransformPoint(contentPanel.position)
            - (Vector2)scrollRect.transform.InverseTransformPoint(target.position);
    }
查看更多
\"骚年 ilove
4楼-- · 2019-04-05 05:43

here's the way I clamped selected object into ScrollRect

private ScrollRect scrollRect;
private RectTransform contentPanel;

public void ScrollReposition(RectTransform obj)
{
    var objPosition = (Vector2)scrollRect.transform.InverseTransformPoint(obj.position);
    var scrollHeight = scrollRect.GetComponent<RectTransform>().rect.height;
    var objHeight = obj.rect.height;

    if (objPosition.y > scrollHeight / 2)
    {
        contentPanel.localPosition = new Vector2(contentPanel.localPosition.x,
            contentPanel.localPosition.y - objHeight - Padding.top);
    }

    if (objPosition.y < -scrollHeight / 2)
    {
        contentPanel.localPosition = new Vector2(contentPanel.localPosition.x,
contentPanel.localPosition.y + objHeight + Padding.bottom);
    }
}
查看更多
贼婆χ
5楼-- · 2019-04-05 05:58

None of the suggestions worked for me, the following code did

Here is the extension

using UnityEngine;
using UnityEngine.UI;

namespace BlinkTalk
{
    public static class ScrollRectExtensions
    {
        public static Vector2 GetSnapToPositionToBringChildIntoView(this ScrollRect instance, RectTransform child)
        {
            Canvas.ForceUpdateCanvases();
            Vector2 viewportLocalPosition = instance.viewport.localPosition;
            Vector2 childLocalPosition   = child.localPosition;
            Vector2 result = new Vector2(
                0 - (viewportLocalPosition.x + childLocalPosition.x),
                0 - (viewportLocalPosition.y + childLocalPosition.y)
            );
            return result;
        }
    }
}

And here is how I used it to scroll a direct child of the content into view

    private void Update()
    {
        MyScrollRect.content.localPosition = MyScrollRect.GetSnapToPositionToBringChildIntoView(someChild);
    }
查看更多
登录 后发表回答