maui: TapGestureRecognizer not working on a Frame in a grid on iOS or Mac

Description

TapGestureRecognizer not working on a Frame in a grid.

Steps to Reproduce

Try the following code:

var frame = new Frame();
frame.GestureRecognizers.Add(new TapGestureRecognizer() { Command = new Command(() => Debug.WriteLine("dfg")) });

Add the frame to a grid, run iOS or Mac and attempt to tap/click on it. [EDIT], It might be more complex, it needs to be in a scrollview that spans all columns in the grid and in a custom layout control. Will put together an example when I get time. [EDIT 2] Ok, nothing to do with my custom control. A grid, containing scrollview that spans columns, containing a frame that has a tap gesture recogniser added will show the problem.

This is using VSforMac, so the .net version is 6.0.301.

Version with bug

Unknown/Other (please specify)

Last version that worked well

Unknown/Other

Affected platforms

iOS, macOS

Affected platform versions

iOS 15

Did you find any workaround?

Nope

Relevant log output

No response

About this issue

  • Original URL
  • State: closed
  • Created 2 years ago
  • Reactions: 4
  • Comments: 16 (6 by maintainers)

Most upvoted comments

Just tested on iOS with Xamarin.Forms and indeed the touches work. Now the trick is to figure out why it is not working in MAUI…

@mattleibow, re your comment, “As far as I can tell, this is how Xamarin.Forms worked.” We discovered this while migrating our code from Xamarin to MAUI. The Xamarin version of our app uses Frame in this way, and it does work on iOS as well as on Android.

Following up on your earlier comment, “Switching to a Border or a CollectionView seems to make it work again”, I modified the test code from my original post to use CollectionView instead of ListView. When I ran it on an iPhone 7 with iOS 15.6.1 and an emulated iPhone 14 with iOS 16.0, the app crashed on startup. I then restored it to use ListView and the app ran as before – i.e. the Frame ignores clicks, but the app didn’t crash on startup. These tests were done using VS 17.4.2.

@rachelkang apologies for the delay, here you go. In the page constructor add the following code. You will see that the tap gesture on the frames don’t work at all. But also, I found that setting the page content itself to a frame, the tap gesture doesn’t work either. So it could be as simple as that to replicate:

            var grid = new Grid();
            grid.ColumnDefinitions.Add(new ColumnDefinition(GridLength.Star));
            grid.ColumnDefinitions.Add(new ColumnDefinition(GridLength.Star));
            grid.ColumnDefinitions.Add(new ColumnDefinition(GridLength.Star));
            grid.ColumnDefinitions.Add(new ColumnDefinition(GridLength.Star));
            grid.ColumnDefinitions.Add(new ColumnDefinition(GridLength.Star));

            grid.RowDefinitions.Add(new RowDefinition(GridLength.Star));
            grid.RowDefinitions.Add(new RowDefinition(GridLength.Star));
            grid.RowDefinitions.Add(new RowDefinition(GridLength.Star));
            grid.RowDefinitions.Add(new RowDefinition(GridLength.Star));
            grid.RowDefinitions.Add(new RowDefinition(GridLength.Star));

            var scrollView = new ScrollView()
            {
                BackgroundColor = Colors.Blue
            };
            Grid.SetRow(scrollView, 0);
            Grid.SetColumn(scrollView, 0);
            Grid.SetColumnSpan(scrollView, 5);
            grid.Children.Add(scrollView);

            var frame1 = new Frame
            {
                BackgroundColor = Colors.Red
            };

            frame1.GestureRecognizers.Add(new TapGestureRecognizer() { Command = new Command(() => Debug.WriteLine("frame1")) });

            scrollView.Content = frame1;

            var frame2 = new Frame
            {
                BackgroundColor = Colors.Green
            };
            frame2.GestureRecognizers.Add(new TapGestureRecognizer() { Command = new Command(() => Debug.WriteLine("frame2")) });
            Grid.SetRow(frame2, 1);
            Grid.SetColumn(frame2, 0);
            Grid.SetColumnSpan(frame2, 5);
            grid.Children.Add(frame2);
            
            Content = grid;

Let me know how you get on!

Thanks John