Scrollview jumps to the top when items are added

I have a UI Toolkit Scrollview in my UI Builder ui that has items added to it in real time. Each time an item is added to it, the scroller jumps to the top and I would like it to stay where it is.

The posts I’ve found about this address different uses, like automatically jumping to the top or bottom. I don’t have any code to show because nothing I can find seems to address this.

I am not scrolling to a specific Visual Element (ScrollTo()) and I’ve tried caching the location with scrolloffset and then resetting it but it doesn’t seem to do the trick.

Any insight would be greatly appreciated,

Thank you.

While not directly related to your problem, I have also had difficulty with setting the scrollOffset of a ScrollView control to a specific location.

In my particular situation, I’ve found that setting the scrollOffset to the maximum value and then subsequently setting it to the desired position works:

_rootDocument.scrollOffset = Vector2.one * float.MaxValue;
_rootDocument.scrollOffset = desiredPosition;

Maybe saving the current scrollOffset and then setting it back in this way after adding the new item will work?

Without this, the ScrollView would often end up with the desired location within the viewable area, but not exactly where I needed it to be. With this change, it reliably sets the actual desired position.

I don’t know why this works or why it would be necessary, but it worked for me and I hope it will work for you.

Had a lot of trouble with this and ended replacing my scrollrects with this.

using UnityEngine;
using UnityEngine.UI;

public class StableScrollRect : ScrollRect
{
    private bool _suppressLayoutJump = false;
    private Vector2 _savedPosition;

    public void SuppressNextLayoutJump()
    {
        _suppressLayoutJump = true;
        _savedPosition = normalizedPosition;
    }

    public override void SetLayoutVertical()
    {
        if (_suppressLayoutJump)
        {
            base.SetLayoutVertical(); // Still update layout
            normalizedPosition = _savedPosition; // Restore position
            _suppressLayoutJump = false;
        }
        else
        {
            base.SetLayoutVertical();
        }
    }
}

Usage

yourScrollRect.SuppressNextLayoutJump();
someGOInScrollrectContent.SetActive(true);

Just noticed that you’re using UI Toolkit so this script may not be applicable but I’ll leave it here for anyone using UGUI that may come across this thread (like I did).