Scroll View touch input on mobile - scroll by drag

Does the runtime Scroll View support touch input (scroll on drag) on mobile?
If so how can I activate it?

This is not supported out of the box. It’s possible to implement yourself by registering for Pointer events on the inner container of ScrollView and possibly on your contents inside ScrollView to capture them before any other element consumes them and determine whether it’s a drag or not. It’s a bit involved. I can give more hints if you want to implement it. We will have proper support for this in a future release though.

Yea that feature would be nice, since it seams to be very easy to implement with the components that are allready there. Something like this worked for me:

private ScrollView scrollView;
private bool dragging = false;
private float mouseYonDragStart = 0;

public Start()
{
//...          
scrollView.RegisterCallback<MouseDownEvent>(OnMouseDown, TrickleDown.TrickleDown);
            scrollView.RegisterCallback<MouseUpEvent>(OnMouseUp, TrickleDown.TrickleDown);
            scrollView.RegisterCallback<MouseMoveEvent>(OnMouseMove, TrickleDown.TrickleDown);

}

private void OnMouseMove(MouseMoveEvent evt)
{
            if (dragging)
            {
                scrollView.scrollOffset = new Vector2(0, mouseYonDragStart-evt.localMousePosition.y);
            }
}

private void OnMouseUp(MouseUpEvent evt)
        {
            dragging = false;
        }

private void OnMouseDown(MouseDownEvent evt)
        {
            dragging = true;
            mouseYonDragStart = evt.localMousePosition.y;
        }
2 Likes

I tried something similar with ListView but was not successful since the ScrolView enbeded in the LisView is only accessable “internal” and the “OnScroll()” Method is “private”.

Why do you program your classes like this? Don’t you want people to extend your Classes? :frowning:

It is the second or third time I ran into such a wall with UIToolkit which make additions that seam to be quite easy really hard to implement.

2 Likes

some Correction:

 private void OnMouseUp(MouseUpEvent evt)
        {
            dragging = false;
            Debug.Log("on mouse up");
            if (Vector2.Distance(dragStart,evt.localMousePosition) > 5)
            {
                evt.StopImmediatePropagation();
            }

        }

This way buttons in the list are not triggert when the list was dragged.

1 Like

@manuelgoellnitz

Thank you,
This is working.

I made a small change, so the scrollview doesn’t jump to the cursor when dragged again.

    private void OnMouseDown(MouseDownEvent evt)
            {
                dragging = true;
                mouseYonDragStart = evt.localMousePosition.y+scrollView.scrollOffset.y;
            }

To make it feel better I would like to make it stop when scrolled over the max and min ScrollOffset.

Preventing it from getting smaller than Zero is easy but how can I detect if the max ScrollOffset is exeeded?

I don’t find the right Variable.

    private void OnMouseMove(MouseMoveEvent evt)
    {
        if (dragging)
        {
            Vector2 oldOffet = scrollView.scrollOffset;
            scrollView.scrollOffset = new Vector2(0, mouseYonDragStart-evt.localMousePosition.y);
          if(scrollView.scrollOffset.y<0)
                scrollView.scrollOffset = oldOffet;
          else if (scrollView.scrollOffset.y>someThing)
               //what is someThing
        }
        
    }

Hehe I did something similar in my version too.

@uDamian Can you give me a hint on this?

This might help:

ScrollView sv;
var range = sv.verticalScroller.slider.range;

Worth also noting that we should have native touch scrolling support in ScrolView in 2021.1.

1 Like

That native scrolling does have a bug: When you end scrolling over elements which Listen to “PointerUpEvent”, that event is not prevented by the scrolling.
I helped myself by listening to “ClickEvent” instead.

2 Likes

Worth also noting that we should have native touch scrolling support in ScrolView in 2021.1.

I am using Unity 2021.2. UIToolkit now ships with Unity.
So I wonder, is there native support for pointer based scrolling when dragging inside the ScrollView?

I notice properties for the ScrollView in UIBuilder:

  • Touch Scroll Type: Clamped
  • Scroll Deceleration Rate: 0.135
  • Elasticity: 0.1

Thus, it seems like the feature is there. But I cannot scroll by dragging inside the ScrollView.
Is this maybe disabled in Unity Editor and only enabled for native touch events (i.e. on mobile)?

To test touch events in the editor, use the Device Simulator.
7683016--960481--upload_2021-11-24_10-39-17.png

1 Like

Thanks Midiphony-panda! That’s kind of a workaround for now.

While touch events work in the simulator there are still some problems with the ScrollView (using Unity 2021.2.3f1)

  • When switching “TouchScrollType” to “Elastic” in the UI Builder it will flip back to “Clamped”
  • Scrolling set to Mode “Vertical” still allows to scroll horizontally (at least in the simulator, did not test on device yet).

In the current state, IMHO this is unusable.

Furthermore I would appreciate to be able to use pointer based scrolling in the Game view as it was with uGUI. The mouse cursor should be treated as a finger like it used to be.

They won’t fix: https://issuetracker.unity3d.com/issues/ui-toolkit-scrollview-touch-scroll-type-option-reverts-to-clamped-when-changing-it-to-other-values

Bug: https://issuetracker.unity3d.com/issues/mobile-scrollview-allows-both-vertical-and-horizontal-movement-when-it-is-set-to-vertical

Here is s thread showcasing many issues with scrollview: https://discussions.unity.com/t/853559

Here is a thread where the last post says the Unity developer is looking into at least one of the issues.

https://discussions.unity.com/t/856928

All we can do is hope their fixed soon!

Is UIToolkit labeled for production atm?

1 Like

Ok when they don’t fix the “Elastic” bug, there will be no “elastic” feature. just “clamped”…

To test touch events in the editor, use the Device Simulator.

Thanks, this works!

I would appreciate to be able to use pointer based scrolling in the Game view as it was with uGUI

I agree, this should be an option. Unity’s best feature is same behavior across platforms, paired with support for lots of platforms.
Thus, I argue that there should be an option to enable the same scrolling behavior in a ScrollView with any pointer based input.
It’s working already when using the simulator. So I guess this would be a matter of adding a checkbox.

When switching “TouchScrollType” to “Elastic” in the UI Builder it will flip back to “Clamped”

This is a bug in the UIBuilder alone. Actually, the UIBuilder sets the value correctly in the uxml file. But it fails to load the value as it seems.

The following behave differently and as one would expect.

<ui:ScrollView touch-scroll-type="Clamped" ...
<ui:ScrollView touch-scroll-type="Elastic" ...
<ui:ScrollView touch-scroll-type="Unrestricted" ...

It iss surprising (like in “WTF Unity?!”) that they closed this UIBuilder issue as “won’t fix”.
To display a different value in UIBuilder than what is present in the uxml file is just wrong.

Anyway, good that the scrolling works (more or less).

I know it’s been a while, but wanted to know if there’s any update on this “touch scrolling” feature being added in finally? My app is touched based (not mobile), and it’s annoying and difficult having to use the scroll bar with your fingers.

So far the “fixes” provided in this thread kind of work, but are buggy. Maybe it’s a simple fix, but using the workaround code above my scrollview has several “controls” inside of it (radiobuttons, toggles…), and when I click one of them and the “pointer” (finger) happens to move by even 1 pixel, the scroll view resets to the top. Also, if my pointer exits the scrollview (which often happens when quickly scrolling with fingers), it doesn’t change the “dragging” bool to false. I tried using “PointerOutEvent”, but doesn’t seem to work correctly. If I debug, the “PointerOutEvent” gets triggered randomly as I’m scrolling.

Using 2022.1.13f1

Any help would be greatly appreciated!

3 Likes