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
22.15k stars 1.74k forks source link

GestureRecognizer Added to parent is intercepted by Child of Frame or GraphicsView Type #6088

Open danielftz opened 2 years ago

danielftz commented 2 years ago

Description

TapGestureRecognizer Added to parent will not be triggered by its Children.

using System.Diagnostics;

namespace GestureBug
{
    public class BugPage : ContentPage
    {
        public BugPage()
        {

            CombinedButton combined;

            TapGestureRecognizer CombinedTap = new();
            CombinedTap.Tapped += (s, e) =>
            {
                Debug.WriteLine("Combined Tapped");
            };

            Content = combined = new CombinedButton()
            {
                WidthRequest = 200,
                HeightRequest = 200,
                HorizontalOptions = LayoutOptions.Center,
                VerticalOptions = LayoutOptions.Center,
            };

            combined.GestureRecognizers.Add(CombinedTap);            
        }
    }

    public class CombinedButton : Grid
    {

        public CombinedButton()
        {
            AddRowDefinition(new RowDefinition());
            AddColumnDefinition(new ColumnDefinition());
            BackgroundColor = Colors.Red;

            Frame frame;
            Label label;

            this.Add(frame = new Frame()
            {
                //WidthRequest = 100,
                //HeightRequest = 100,
                HorizontalOptions = LayoutOptions.Fill,
                VerticalOptions = LayoutOptions.Fill,
                BackgroundColor = Colors.Orange,
                Content = label = new Label()
                {
                    Text = "Click me",
                    HorizontalOptions = LayoutOptions.Center,
                    VerticalOptions = LayoutOptions.Center,
                    Background = Colors.Yellow,
                }
            }, 0, 0);
        }
    }
}

In this example, clicking the the CombinedButton will not trigger TapGestureRecognizer, even though none of the children view has a GestureRecognizer attached to it.

Steps to Reproduce

See Description

Version with bug

Release Candidate 1 (current)

Last version that worked well

Preview 14

Affected platforms

Android, I was not able test on other platforms

Affected platform versions

31

Did you find any workaround?

If Frame is exchanged with ContentView or Grid, the Gesture falls through. to the GestureRecognizer as expected. This seems to be an issue with Frame, and GraphicsView

Relevant log output

No response

v-longmin commented 2 years ago

@danielftz Could you share your repro project for us so that we can reproduce this issue? Thanks.

ghost commented 2 years ago

Hi @danielftz. 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.

danielftz commented 2 years ago

@danielftz Could you share your repro project for us so that we can reproduce this issue? Thanks.

https://github.com/danielftz/GestureBug.Maui

v-longmin commented 2 years ago

Verified repro on Android 12.0 - API 31 with VS 17.2.0 preview 2.1 [32317.152]. Repro project: GestureBug.Maui-main.zip

IeuanWalker commented 2 years ago

Also having this issue migrating my custom control to MAUI - https://github.com/IeuanWalker/Xamarin.Forms.CustomSwitch/blob/cbbe8e73c267f2072a1c1d69ad4fd1fac4dea173/Src/Switch/CustomSwitch.xaml#L10

VWilcox2000 commented 2 years ago

This is also an issue on Preview 14 with 6.0.312 on Android.

Where I have nested Frames, I have just been copying the section to all the frames which is a nice workaround.

It is more annoying for my custom gesture recognizers (long press, short press, etc.) where I would rather nested frames honor InputTransparent="True", but they still eat all touch events.

      <Frame HorizontalOptions="FillAndExpand"
             VerticalOptions="Fill"
             BorderColor="#b0afb0"
             Margin="0"
             Padding="0"
             CornerRadius="0"
             HasShadow="False"
             Background="{Binding WhiteGradient}">
        <Frame.GestureRecognizers>
          <TapGestureRecognizer Command="{Binding closeCaseDetails}" />
          <SwipeGestureRecognizer Direction="Down"
                                  Command="{Binding expandCasePanel}" />
          <SwipeGestureRecognizer Direction="Up"
                                  Command="{Binding collapseCasePanel}" />
        </Frame.GestureRecognizers>
        <Frame HorizontalOptions="Fill"
               VerticalOptions="Fill"
               Margin="8,6,8,0"
               Padding="0"
               BackgroundColor="Transparent"
               BorderColor="Transparent"
               HasShadow="False">
          <Frame.GestureRecognizers>
            <TapGestureRecognizer Command="{Binding closeCaseDetails}" />
            <SwipeGestureRecognizer Direction="Down"
                                    Command="{Binding expandCasePanel}" />
            <SwipeGestureRecognizer Direction="Up"
                                    Command="{Binding collapseCasePanel}" />
          </Frame.GestureRecognizers>

is the pattern I used to work around the bug with built-in gestures. Note: Adding InputTransparent="True" on the nested Frame is ineffective -- but it fires the same gesture as the parent in this case.

VWilcox2000 commented 2 years ago

In regards to my previous post, I recently discovered the Border control -- which acts a lot like the PancakeView for Xamarin. I had previously been surprised not to see Frame on MAUI support multiple corner radii, but with Border, I can render frames with gradient backgrounds, varying corner radii, and they do not grab up gestures. I have not discovered any downsides to using this control, so I may end up using it almost every time I would otherwise use a Frame. You do not need InputTransparent either. This behaves as frames did in Xamarin.

    <Border 
            Padding="4"
            BackgroundColor="#d9d9d9"
            Stroke="#d9d9d9"
            Background="{Binding WhiteGradient}">
      <Border.StrokeShape>
        <RoundRectangle CornerRadius="14, 33, 0, 0" />
      </Border.StrokeShape>
ghost commented 2 years ago

We've moved this issue to the Backlog milestone. This means that it is not going to be worked on for the coming release. We will reassess the backlog following the current release and consider this item at that time. To learn more about our issue management process and to have better expectation regarding different types of issues you can read our Triage Process.

Zhanglirong-Winnie commented 1 year ago

Verified this issue with Visual Studio Enterprise 17.7.0 Preview 5.0. Can repro on android platform with sample project. GestureBug.Maui-main.zip