dotnet / maui

.NET MAUI is the .NET Multi-platform App UI, a framework for building native device applications spanning mobile, tablet, and desktop.
https://dot.net/maui
MIT License
21.82k stars 1.66k forks source link

ScrollView could (?) propagate touch events to children #18547

Open beto-rodriguez opened 7 months ago

beto-rodriguez commented 7 months ago

Description

I am trying to find a way to get the touch event in a control inside a scroll view.

When the ScrollView is scrolled, the children do not receive the event anymore.

Public API Changes

I am not sure, maybe a property where we can control if the ScrollView handles the event?

Intended Use-Case

I am using the touch event in a chart control to show tooltips and also zooming and panning, when the control is inside a ScrollView, it is complicated to interact with the chart, because the ScrollView is not propagating the event.

image

More info: https://github.com/beto-rodriguez/LiveCharts2/issues/1343

mattleibow commented 7 months ago

I think there may be some confusion by the swipe: when you swipe, do you expect the touch to go to the scroll or the chart? And how would you toggle the other way?

One thing that may work is to add some pointer events or something similar to detect when a touch happens in the chart and then disable the scrollview scroll - maybe using scrollview.InputTransparent = true.

I think right now the scroll view always takes priority (or at least the way livecharts is designed) and this is bad for your case. But, I have seen cases where they want the opposite and don't like when "touch-aware" views prevent the scrolling and you have to find a thin slice of the UI to drag.

ghost commented 7 months ago

Hi @beto-rodriguez. We have added the "s/needs-info" label to this issue, which indicates that we have an open question for you before we can take further action. This issue will be closed automatically in 7 days if we do not hear back from you by then - please feel free to re-open it if you come back to this issue after that time.

beto-rodriguez commented 7 months ago

Thanks for the reply @mattleibow, I tried the InputTransparent but sadly that will not work, because it disables the input of the ScrollView and all of its children.

I finally managed to make this work on Android, using the Android.Views.ViewGroup.RequestDisallowInterceptTouchEvent, for me I set a threshold (20% of the chart height) if the vertical scroll is greater than it, then I release the touch event, so the ScrollView can do its thing.

But now I have to find the IOS API to achieve that also, I am not sure if there is something Maui could to to make this easier, but I think that for now using the native API seems the best option.

mattleibow commented 7 months ago

@beto-rodriguez Not sure if this will work, but I wonder if you might it to work if you set the root layout of the scrollview to InputTransparent="false". I am not sure how the scrollview or content view handles this type of thing, but maybe it is something we need to look at.

Not sure about the iOS unfortunately.

beto-rodriguez commented 7 months ago

I think this is now working properly for me using native events.

The ScrollView behaves different (or seems) on both platforms (Android and iOS).

On iOS the event is not handled by the scrollview, when the ScrollView is scrolled, the event is also propagated to the chart, all I had to do was set the ShouldRecognizeSimultaneously to true (here).

On Android I was not able to get the event in both (The ScrollView and the control) so I had to build this workaround (code here).

I leave this note here just in case it is useful for the team, maybe you can suggest me a better alternative.

beto-rodriguez commented 7 months ago

Probably related to #13628

Phenek commented 6 months ago

9827

BioTurboNick commented 3 days ago

@beto-rodriguez :

I finally managed to make this work on Android, using the Android.Views.ViewGroup.RequestDisallowInterceptTouchEvent, for me I set a threshold (20% of the chart height) if the vertical scroll is greater than it, then I release the touch event, so the ScrollView can do its thing.

Amazing, this was exactly what I needed. In my case I don't want any touches inside the control to propagate to the scroll view, so just dropping (sender as ViewGroup)?.RequestDisallowInterceptTouchEvent(true); into the ContentView_Touch(object? sender, View.TouchEventArgs e) handler on Android.