How to refresh ScrollView scrollbars to reflect changed content width and height?

This is the structure of my content:


I’m adding visualElements under the container #TimelinePillList and #TimelineChildPillList via script. However, the parent ScrollView (VerticalAndHorizontal-mode and “Infinite” scrolling) scroll bars won’t reflect the new size of the the content - they simply won’t update. If I click the buttons at the sides of the scroll bar, I can make it scroll to the content when in Elastic or Infinite -scroll mode, but the scroll bar width and height (the bar itself) doesn’t update. Is there a way to force update the ScrollView UI, to tell it that it should check the new content width and height? It doesn’t seem to do this automatically.

2 Likes

It’s hard to tell without investigating the actual project. It seemed to work on my end (21.2.10f1), when I added nested VisualElements to a ScrollView. Are you using absolute positioning? If you suspect this is a bug, don’t hesitate to submit a repro through the bug reporter in Help > Report a bug…

Hi! Thanks for the quick reply. I query the #TimelinePillList inside the ScrollView and add elements to it. Yes, I’m using absolute positioning to add them inside the #TimelinePillList-container. Is this something that could cause the behaviour?

I talked with the team and it should work for both. I managed to repro in UI Builder though, with this simple UI:

    <ui:ScrollView scroll-deceleration-rate="0,135" elasticity="0,1" style="width: 100%; height: 100%;">
        <ui:VisualElement name="Outer" style="background-color: rgb(4, 255, 0);">
            <ui:VisualElement name="Inner" style="width: 200px; height: 100px; background-color: rgb(0, 17, 255); position: absolute;" />
        </ui:VisualElement>
    </ui:ScrollView>

When setting the height of the nested VisualElement to 1000, the scroll bars don’t immediately appear, I had to save the UXML (which forces a reload). I’ll submit my repro through the bug reporter and post the case number here so you can track it.

Wow, thank you so much! :slight_smile: So the workaround is to adjust #unity-content-container width and height manually - this will make ScrollView bars update?

Hmm, updating unity-content-container manually (via query and then unityContentContainerVisualElement.style.width = newWidth) doesn’t seem to force update. Is there a way (as a workaround) - to force the scrollbar reload by script?

Just for the follow-up - did you already get the case number for this? Did you happen to come up a workaround while waiting? Updating the content-container manually doesn’t make the scrollbars refresh. I still haven’t found a way to force them refresh.

Hello! You can track the issue here: Unity Issue Tracker - [UIToolkit] ScrollView scroll bars aren&#39;t refreshed after changing its size

1 Like

Could perhaps the people who have run into this issue vote for the issue please? :wink:
My vote is currently the only one.

I assume nobody has a workaround?

Okay, found the workaround that was hinted at earlier.
Changing the size of the scroll view does the trick, however you may not set it to the value it already has. Here I just alternate it between “99.999%” and “100%”

    bool scale_swap = true;
    void ForceUpdateScrollViewScale()
    {
        var new_len = new StyleLength(UnityEngine.UIElements.Length.Percent(scale_swap ? 99.999f : 100f));
        scroll_view.style.width = new_len;
        scroll_view.style.height = new_len;
        scale_swap = !scale_swap;
    }

I can solve this problem by using the asynchronous method of Dotween (http://dotween.demigiant.com/), which resets the height of the scroller after a delay of 0 seconds.

float h = scroller.resolvedStyle.height;
        scroller.style.height = 0;
        DOVirtual.DelayedCall(0, () => {
          scroller.style.height = h;
        });

But it should be solved by using Coroutine as well.

Am seeing that this ticket has been closed with “By Design”.
Well, what is the right way to solve the problem we encountered then?

Being able to dynamically change content of a scrollview in such a way that the scrollbars adapt feels rather fundamental to me. If not fully automated, at least provide some “EnforceRefresh” method please as the workaround is simply hacky and not reliable.
For example on lower resolutions, the “99.999f” is too little of a difference to trigger the refresh.

P.s. MarkDirtyRepaint does not work.

That flickers ugly as for one frame the element is nullified. On my side since at least.

1 Like

Still waiting for a fix. Or even a reliable workaround @AlexandreT-unity

1 Like

I asked @alexandred_unity , who closed the case, and he mentioned this workaround:

void ForceUpdate(ScrollView view)
{
    view.schedule.Execute(() =>
    {
        var fakeOldRect = Rect.zero;
        var fakeNewRect = view.layout;
       
        using var evt = GeometryChangedEvent.GetPooled(fakeOldRect, fakeNewRect);
        evt.target = view.contentContainer;
        view.contentContainer.SendEvent(evt);
    });
}
9 Likes

This will happen if the ScrollView set to Wrap… but the workaround
@AlexandreT-unity gave, worked

1 Like

Just hit this issue as well.

I have a tab based panel layout, where each panel contains a scrollView.
Switch between panels removes and adds them to a parent container.
When switching panels, the scrollView contained within doesn’t update.

You can get into a situation where you’ve scrolled to the bottom of one panel, switch to another that wasn’t as tall, and the content is not visible, since the scrollView hasn’t updated its size.

The fix @AlexandreT-unity gave kinda works (still can get into a situation where the scrollView doesn’t update). But is this seriously what we’re expected to do?
If so, why isn’t this just part of the ScrollView class?

@stevphie123 what do you mean by scrollView set to wrap?

1 Like

Ran into this issue as well and I am more than a little bit surprised that this, let’s be honest, hack is “by design” and enough to close the issue?

5 Likes

Also just ran into this. Can we get someone from Unity to comment on this? This is just broken behavior.

3 Likes

Ran into this myself into Unity 2021 LTS. The proposed “ForcedUpdate” works for me so far.

Incredibly frustrating to see how broken and ‘unfinished’ the scrollview is in Unity UI Toolkit.

Apparenty I spoke too soon. Found a problem even with the proposed “fix”.

I have a scrollview initially filled with lots of elements (top left image). Then, clicking on a radio button, I clear it and populate with others (top right image). Just enough, so the scrollview doesn’t actually needs a scrollbar, so it disappears.

Then, if I change it back to show the first elements (bottom left), they all show up, but the vertical scrollbar won’t show.

If I change the scrollbar from ‘auto’ to ‘always visible’, it stays on screen, but it doesn’t update.