Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Have a look at our Games Focus blog post series which will show what Unity is doing for all game developers – now, next year, and in the future.
    Dismiss Notice

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

Discussion in 'UI Toolkit' started by herra_lehtiniemi, Mar 31, 2022.

  1. herra_lehtiniemi

    herra_lehtiniemi

    Joined:
    Feb 12, 2017
    Posts:
    114
    This is the structure of my content: upload_2022-3-31_12-47-23.png
    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.
     
    DragonCoder likes this.
  2. AlexandreT-unity

    AlexandreT-unity

    Unity Technologies

    Joined:
    Feb 1, 2018
    Posts:
    282
    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...
     
  3. herra_lehtiniemi

    herra_lehtiniemi

    Joined:
    Feb 12, 2017
    Posts:
    114
    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?
     
  4. AlexandreT-unity

    AlexandreT-unity

    Unity Technologies

    Joined:
    Feb 1, 2018
    Posts:
    282
    I talked with the team and it should work for both. I managed to repro in UI Builder though, with this simple UI:
    Code (CSharp):
    1.     <ui:ScrollView scroll-deceleration-rate="0,135" elasticity="0,1" style="width: 100%; height: 100%;">
    2.         <ui:VisualElement name="Outer" style="background-color: rgb(4, 255, 0);">
    3.             <ui:VisualElement name="Inner" style="width: 200px; height: 100px; background-color: rgb(0, 17, 255); position: absolute;" />
    4.         </ui:VisualElement>
    5.     </ui:ScrollView>
    6.  
    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.
     
  5. herra_lehtiniemi

    herra_lehtiniemi

    Joined:
    Feb 12, 2017
    Posts:
    114
    Wow, thank you so much! :) So the workaround is to adjust #unity-content-container width and height manually - this will make ScrollView bars update?
     
  6. herra_lehtiniemi

    herra_lehtiniemi

    Joined:
    Feb 12, 2017
    Posts:
    114
    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?
     
  7. herra_lehtiniemi

    herra_lehtiniemi

    Joined:
    Feb 12, 2017
    Posts:
    114
    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.
     
  8. cpalma-unity

    cpalma-unity

    Unity Technologies

    Joined:
    Nov 30, 2020
    Posts:
    48
  9. DragonCoder

    DragonCoder

    Joined:
    Jul 3, 2015
    Posts:
    857
    Could perhaps the people who have run into this issue vote for the issue please? ;)
    My vote is currently the only one.

    I assume nobody has a workaround?
     
  10. DragonCoder

    DragonCoder

    Joined:
    Jul 3, 2015
    Posts:
    857
    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%"

    Code (CSharp):
    1.  
    2.     bool scale_swap = true;
    3.     void ForceUpdateScrollViewScale()
    4.     {
    5.         var new_len = new StyleLength(UnityEngine.UIElements.Length.Percent(scale_swap ? 99.999f : 100f));
    6.         scroll_view.style.width = new_len;
    7.         scroll_view.style.height = new_len;
    8.         scale_swap = !scale_swap;
    9.     }
     
  11. littenli

    littenli

    Joined:
    Dec 18, 2019
    Posts:
    33
    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.

    Code (CSharp):
    1. float h = scroller.resolvedStyle.height;
    2.         scroller.style.height = 0;
    3.         DOVirtual.DelayedCall(0, () => {
    4.           scroller.style.height = h;
    5.         });
    But it should be solved by using Coroutine as well.
     
  12. DragonCoder

    DragonCoder

    Joined:
    Jul 3, 2015
    Posts:
    857
    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.
     
    Last edited: Nov 4, 2022
    UltiPangol likes this.