Forum Xamarin.Forms
We are excited to announce that the Xamarin Forums are moving to the new Microsoft Q&A experience. Q&A is the home for technical questions and answers at across all products at Microsoft now including Xamarin!

We encourage you to head over to Microsoft Q&A for .NET for posting new questions and get involved today.

TapGestureRecognizer - using NumberOfTapsRequired for double tap

Ideally I'm looking for a LongTap event or GestureRecognizer but as yet that doesn't exist in .Forms (hopefully next release!) so as a temporary workaround to my situation where my app normally uses tap to open and longtap (tap and hold) to show a popup context menu I thought I'd use tap to open and double tap to show the context menu as TapGestureRecognizer has a property NumberOfTapsRequired which should do the trick .. however I'm having problems working out how to do this.

Based on the following code, whilst the second doubletapped function is indeed only called when a double tap occurs, the first tapped function is called both for a tap and a double tap but without any way as far as I can tell to know in the tapped function that this is a double tap and hence to ignore it.

    public someObject() : base()
    {
        var tgr = new TapGestureRecognizer();
        tgr.NumberOfTapsRequired = 1;
        tgr.Tapped += tapped;
        GestureRecognizers.Add(tgr);

        var ttgr = new TapGestureRecognizer();
        ttgr.NumberOfTapsRequired = 2;
        ttgr.Tapped += doubletapped;
        GestureRecognizers.Add(ttgr);
    }
    private void tapped(object sender, EventArgs e)
    {
    // deal with tap
    }
    private void doubletapped(object sender, EventArgs e)
    {
        // deal with doubletap
    }

I would've hoped that perhaps in the EventArgs of tapped it would have the number of taps so I could then ignore double taps within it or is there some other way to deal with it?

Thanks

Answers

  • RyanHatfieldOldRyanHatfieldOld USMember, Insider ✭✭✭

    I would flip those around, add the double tapped recognizer first, then the single tap one

    from the doubletapped method, set a DateTime LastDoubleTapped that you declare globally, then inside the tapped method, check if LastDoubleTapped happened recently. No idea if that'll work, but worth a try (I'd normally try it myself but I don't have any time today)

    Snail

  • DanielLDanielL PLInsider ✭✭✭✭

    @DerekPapworth‌
    I would use a timer:

    • 1st TapGestureRecognizer - start the timer, tick method set to "tapped"
    • 2nd TapGestureRecognizer - stop the timer and invoke "doubletapped"
  • DerekPapworth.4183DerekPapworth.4183 GBMember ✭✭
    edited July 2014

    Thanks for the ideas @RyanHatfield @DanielL‌

    Ryan's thought on switching the sequence I thought was a goer and tried that with rather than a datetime just an instance bool variable "taphandled" in the double tape one setting to true and then in the tapped check if true, ignore and set false but .. even with them flipped around the tap gets called before the doubletap so that didn't work.

    Haven't tried Daniels idea yet but sounds a possible .. any thoughts on how long to allow the timer? As presume I need to use the timeout to then say "ok, no double tap occurred so do tap stuff"

  • RyanHatfieldOldRyanHatfieldOld USMember, Insider ✭✭✭

    As long as you want the double tap. I see this having issues though.. what if the app laggs? what if _____ something happens?

    And you didn't ask for it but here's my 2 cents:

    Just stop and think of how many apps on your phone require a double tap. I don't think it's a normal mobile gesture. Double tap is OK, but not when there's also a single tap. A user should be able to figure out the gesture without very much instruction. I would suggest a long press or a swipe.

  • DanielLDanielL PLInsider ✭✭✭✭

    @RyanHatfield‌ My position is similar but the problem is that Xamarin.Forms doesn't have swipe and long press gesture recognizers.

  • RyanHatfieldOldRyanHatfieldOld USMember, Insider ✭✭✭

    @DanielL Then let's make one!

  • DanielLDanielL PLInsider ✭✭✭✭

    @RyanHatfield‌ I tried :) but.... GestureRecognizer is internal

  • RyanHatfieldOldRyanHatfieldOld USMember, Insider ✭✭✭

    @DanielL‌ Challenge Accepted.

  • DanielLDanielL PLInsider ✭✭✭✭

    @RyanHatfield‌ Good luck! PM me if you need any help =]

  • DerekPapworth.4183DerekPapworth.4183 GBMember ✭✭
    edited July 2014

    Hi guys, @RyanHatfield @DanielL

    Yes agree with all said, I don't really want to use doubletap for this, as mentioned at first it's merely as longtap doesn't yet exist in .Forms so hence was using doubtletap as temporary method to continue my app development with view to replace longtap when available so ..

    .. if we can come up with a longtap that'd be great! :) .. I tried looking myself at it but I can't seem to find any form of "release" gesture in .Forms to allow a combination of tap gesture, timer and release gesture to base one on .. any thoughts on that?

    By way of completeness on the doubletap front though, here's what I ended up doing for that for now :

    private bool tapHandled;
    
        public uuiImage() : base()
        {
            var tgr = new TapGestureRecognizer();
            tgr.NumberOfTapsRequired = 1;
            tgr.Tapped += tapped;
            GestureRecognizers.Add(tgr);
    
            var ttgr = new TapGestureRecognizer();
            ttgr.NumberOfTapsRequired = 2;
            ttgr.Tapped += doubletapped;
            GestureRecognizers.Add(ttgr);
        }
        private void tapped(object sender, EventArgs e)
        {
            tapHandled = false;
            Xamarin.Forms.Device.StartTimer(new TimeSpan(0, 0, 0, 0, 300), taptimer);
        }
        private void doubletapped(object sender, EventArgs e)
        {
            tapHandled = true;
            // do stuff here
        }
        private bool taptimer()
        {
            if (!tapHandled)
            {
                tapHandled = true;
                // do stuff here
            }
            return false;
        } 
    
  • DerekPapworth.4183DerekPapworth.4183 GBMember ✭✭

    Just discovered the numberoftapsrequired doesn't seem to have any effect in Android as the function doubletapped never gets called in the above code .. anyone else have that working or not?

  • CraigDunnCraigDunn USXamarin Team Xamurai

    Unfortunately this is a known issue (NumberOfTapsRequired not working on Android), already in our backlog. Not sure what the timeframe to fix is, but we are aware of it!

  • Any news on NumberOfTapsRequired fix in Android?

  • Xami3Xami3 PKMember, University ✭✭✭
    edited March 2015

    @CraigDunn Any updates on "NumberOfTapsRequired not working issue on Android"?
    this is the code i am using with XF version 1.4.0.6341 Stable. still double tap isnot working

    var gesture = new TapGestureRecognizer();
    gesture.NumberOfTapsRequired = 2;
    gesture.Command = new Command(TapGestuer);
    gesture.CommandParameter = Indexes.FieldType.ChangeBaseUrl;
    var img = //My Image

    img.GestureRecognizers.Add(gesture);

  • Xami3Xami3 PKMember, University ✭✭✭

    @DerekPapworth @CraigDunn
    this is how i do it for now :
    private void TapGestuer(object o)
    {
    tapCount++;
    if (tapCount >= 7)
    {
    tapCount = 0;
    //TODO Perform my action
    }
    if (!isTimerSet)
    {
    isTimerSet = true;
    Device.StartTimer(new TimeSpan(0, 0, 0, 2, 0), () =>
    {
    isTimerSet = false;
    tapCount = 0;
    return false;
    });
    }
    }

  • FredyWengerFredyWenger CHInsider ✭✭✭✭✭

    At all readers of this thread.
    I have tried to add a tapGestureRecognizer with NumberOfTapsRequired = n to a label (to show a password entry, if tapped the specific times).
    Unfortunately this is not usable on iOS (as the taps have to be took place in a specific time and the time can't be set.) :disappointed:
    So from 10 attempts, maybe one attempt is done in the "estimated" time -> not usable at least not for NumberOfTapsRequired >=4.
    So I have re-activated my "old" solution to count the taps myself (similar to the example of @lXami3), as it also is not usable on iOS.

    This also don't work perfect, but better than with "NumberOfTapsRequired".

    Hope this helps someone...

  • yogesh.0489yogesh.0489 USMember

    Hi,

    How to do single tap event fire for multiple click events on label or Image?

  • SolomonFriedSolomonFried USMember ✭✭

    @DerekPapworth.4183 said:
    Hi guys, @RyanHatfield @DanielL

    Yes agree with all said, I don't really want to use doubletap for this, as mentioned at first it's merely as longtap doesn't yet exist in .Forms so hence was using doubtletap as temporary method to continue my app development with view to replace longtap when available so ..

    .. if we can come up with a longtap that'd be great! :) .. I tried looking myself at it but I can't seem to find any form of "release" gesture in .Forms to allow a combination of tap gesture, timer and release gesture to base one on .. any thoughts on that?

    By way of completeness on the doubletap front though, here's what I ended up doing for that for now :

    private bool tapHandled;

        public uuiImage() : base()
        {
            var tgr = new TapGestureRecognizer();
            tgr.NumberOfTapsRequired = 1;
            tgr.Tapped += tapped;
            GestureRecognizers.Add(tgr);
    
            var ttgr = new TapGestureRecognizer();
            ttgr.NumberOfTapsRequired = 2;
            ttgr.Tapped += doubletapped;
            GestureRecognizers.Add(ttgr);
        }
        private void tapped(object sender, EventArgs e)
        {
            tapHandled = false;
            Xamarin.Forms.Device.StartTimer(new TimeSpan(0, 0, 0, 0, 300), taptimer);
        }
        private void doubletapped(object sender, EventArgs e)
        {
            tapHandled = true;
            // do stuff here
        }
        private bool taptimer()
        {
            if (!tapHandled)
            {
                tapHandled = true;
                // do stuff here
            }
            return false;
        } 
    

    I know this thread is a bit old, but I just ran into the same issue.
    This solution seems to work.
    Interestingly, on Android it just works. A double tap will not trigger a tap.
    On Windows and iOS, this type of tap handling is required if you need Single and Double Tap handlers.

  • Jay_khilosiyaJay_khilosiya Member
    edited February 4

    how to apply zoom in and zoom out on ImageView with doubletap and explain with code

Sign In or Register to comment.