1

How do I create different methods when double-tap vs. single-tap? How to recreate:

  1. Take the default "New Maui App"
  2. Add the first two code blocks from this documentation: https://learn.microsoft.com/en-us/dotnet/maui/fundamentals/gestures/tap?view=net-maui-7.0
  3. Then add a second function for single-tap The MainPage.Xaml now looks like this (truncated after image part since the rest is the same):
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="MauiApp2.MainPage">

    <ScrollView>
        <VerticalStackLayout
            Spacing="25"
            Padding="30,0"
            VerticalOptions="Center">

            <Image
                Source="dotnet_bot.png"
                SemanticProperties.Description="Cute dot net bot waving hi to you!"
                HeightRequest="200"
                HorizontalOptions="Center" >
                <!--******* add gesture recognizers to default app ******-->
                <Image.GestureRecognizers>
                    <TapGestureRecognizer Tapped="OnTapGestureRecognizerDoubleTapped"
                              NumberOfTapsRequired="2" />
                    <TapGestureRecognizer Tapped="OnTapGestureRecognizerSingleTapped"
                              NumberOfTapsRequired="1" />
                </Image.GestureRecognizers>
                <!--******** end add gesture recognizers to default app *******-->
            </Image>

            <Label
                Text="Hello, World!"
...

Then in MainPage.xaml.cs, I've added the two methods:

    void OnTapGestureRecognizerDoubleTapped(object sender, TappedEventArgs args)
    {
        CounterBtn.Text = $"Double tapped image";

    }
    void OnTapGestureRecognizerSingleTapped(object sender, TappedEventArgs args)
    {
        CounterBtn.Text = $"Single tapped image";

    }

Now, when you run and double-click/tap the image, it goes first to the single-tap method, then the double-tap method, then back to the single-tap method.

What is the best way to prevent calls to the single-tap method?

mattica
  • 357
  • 3
  • 8
  • 1
    I don't think you can combine two tap gestures this way. You could try using a single tap gesture and track if a 2nd tap is received within some time span – Jason Jan 14 '23 at 23:36

3 Answers3

1

based on these comments, I implemented the double-tap vs single-tap like this:

    bool doubleTapped;
    bool ignoreNextTap;
    void OnTapGestureRecognizerDoubleTapped(object sender, TappedEventArgs args)
    {
        doubleTapped = true;
    }
    async void OnTapGestureRecognizerSingleTapped(object sender, TappedEventArgs args)
    {
        var delay = Task.Delay(555);
        await delay;
        if (ignoreNextTap)
        {
            ignoreNextTap = false;
            return;
        }
        if (doubleTapped)
        {
            doubleTapped = false;
            ignoreNextTap = true;
            CounterBtn.Text = $"Double tapped image";
        }
        else
        {
            CounterBtn.Text = $"Single tapped image";
        }
    }

It works, but it sure seems hacky. Basically, what single tap method sleeps for half-of-a-second, to see if the doubleTapped flag will be raised. If it is, then it calls the code that should be executed for doubleTap ("CounterBtn.Text = $"Double tapped image";"). Otherwise, it calls the singleTap code ("CounterBtn.Text = $"Single tapped image";"). However, in order to prevent the second single click from registering, I put another Boolean for ignoreNextTap. I saw similar posts from other languages (How to customize singleclick to doubleclick? js) and the general approach is the same as this. I guess there is no other way to do this other than the Delay/Sleep approach to see if a second click happens. This will generally cut into the snappy-ness of the UI.

mattica
  • 357
  • 3
  • 8
1

For me it works as intended with a border control. One tap goes to the first method and two taps go to the second method:

                <Border.GestureRecognizers>
                <TapGestureRecognizer NumberOfTapsRequired="1" Tapped="TapGestureRecognizer_Tapped" />
                <TapGestureRecognizer NumberOfTapsRequired="2" Tapped="TapGestureRecognizer_Tapped_2" />
            </Border.GestureRecognizers>

//Code behind

private void TapGestureRecognizer_Tapped(object sender, TappedEventArgs e)
    {
        //tapped once
    }

    private void TapGestureRecognizer_Tapped_2(object sender, TappedEventArgs e)
    {
        //tapped twice
    }
Faraz
  • 45
  • 1
  • 7
0

By default, the Image will respond to single taps. So single-tap method would be triggered at first tap. When the NumberOfTapsRequired property is set to greater than one, the event handler will only be executed if the taps occur within a set period of time. If the second (or subsequent) taps don't occur within that period, they're effectively ignored.

So as Jason suggested, it's better to use a single tap gesture and track if a 2nd tap is received within some time span.

Alexandar May - MSFT
  • 6,536
  • 1
  • 8
  • 15