Forum Xamarin.Forms

MR.Gestures handles ALL touch gestures



  • MichaelRumplerMichaelRumpler ATMember ✭✭✭✭✭

    @aisac In the PanEventArgs you have DeltaDistance and Velocity. These are much more accurate than the Direction.

  • JensDemeyJensDemey USMember ✭✭

    @MichaelRumpler said:

    • no events are raised if InputTransparent == true (on iOS there are also no events if any container has InputTransparent)

    @JohnEeckhout requested this and I rejected it first because it is a breaking change. But as I raised the minor version now, I think it is ok.

    Hello @MichaelRumpler
    Regarding these different behaviors between the different platforms. Wouldn't it make sense for all platforms to follow the iOS way (unless there's something technical limiting you from making it the same behavior)
    It would significantly reduce the code needed to make it work as expected (For example you don't have to worry about dynamically added elements).

  • WilliamSmithWilliamSmith USMember
    edited March 2017

    Hello @MichaelRumpler
    I have implemented the Swipe gesture in a custom listview cell. What I'm noticing on Android devices (we haven't begun to work on our iOS implementation yet) is that the user must be very deliberate in swiping horizontally.

    At first I thought this was just behavior in the emulator since swiping with a mouse is easier said than done! However, QA is reporting the same experience on physical devices and it is taking sometimes 5 to 10 tries to get the swipe to fire properly.

    Here's our XAML:

        <mr:Grid x:Name="CellGrid"

    And here's how we're handling the event:

        private void CellGrid_Swiped(object sender, SwipeEventArgs e)
            var swipeLimit = PanCell.Width * 0.20;            
            _panCellX = 0;
            switch (e.Direction)
                case Direction.Left:
                    if (PanCell.TranslationX == 0)
                        _panCellX = -swipeLimit;
                case Direction.Right:
                    if (PanCell.TranslationX == 0)
                        _panCellX = swipeLimit;
            Device.BeginInvokeOnMainThread(async () =>
                await PanCell.TranslateTo(_panCellX, 0, 150, Easing.SinIn);
                PanCell.TranslationX = _panCellX;
                if (_panCellX != 0)
                    MessagingCenter.Send<IssueManagementCellView, long>(this, "CenterPanCell", ActionItemId.Value);

    As you can see we're not doing anything really special with regards to the Swiped event. We are using a licensed ersion of the library. Is there anything you can suggest to help us improve on the UX we're seeing? Thanks in advance.

  • MichaelRumplerMichaelRumpler ATMember ✭✭✭✭✭

    @JensDemey said:
    Regarding these different behaviors between the different platforms. Wouldn't it make sense for all platforms to follow the iOS way (unless there's something technical limiting you from making it the same behavior)

    This difference is nothing I implemented. That comes from the OS and the way Xamarin.Forms handles it. I didn't handle InputTransparent at all before and I still don't look at any child or parent elements when I handle gesture events. I handle all controls the same.

  • MichaelRumplerMichaelRumpler ATMember ✭✭✭✭✭

    Android and Windows try to optimize the scroll performance and consume pan events in ListViews (and ScrollViews) when they think these events are for them. So if you start your swipe gesture not exactly horizontal, then they think it is a vertical scroll and don't forward any events to me. Unfortunately there's nothing I can do about that. Or at least I don't know how. If you find something, then please let me know.

  • WinSomeLoseSomeWinSomeLoseSome USMember ✭✭

    I'm trying to make sure MR.Gestures will handle Swipe gestures on a ListView for Android and iOS devices before I buy it. It looks like a valid license key is required for the SwipeDirection to come back as anything except "NotClear". Can someone confirm this works properly? I've seen others having this problem and Michael suggesting this be tweaked, but none of the values I have tried are making a difference.

    MR.Gestures.Android.Settings.SwipeVelocityThreshold = (float).17;

  • WinSomeLoseSomeWinSomeLoseSome USMember ✭✭

    Michael Rumpler, when I try to use your license key I get an error in both Andriod and iOS versions saying the license key isn't valid. When I comment out the line that throws the exception just mentioned, it runs but the values are missing which is why I asked the question. Testing on iOS shows the events weren't even firing without the key making it impossible to evaluate for my needs before buying.

  • ShawnCastrianni.5092ShawnCastrianni.5092 US ✭✭✭
    edited March 2017
    @PatrickMagee.5014 make sure to temporarily rename your app to "GestureSample" in order to use the trial license key. Mr.Gestures license keys are validated against the app name.
  • WinSomeLoseSomeWinSomeLoseSome USMember ✭✭
    edited March 2017

    Thank you @ShawnCastrianni.5092. All of the MRGesture features I need are working in the sample app. However, your suggestion will allow me evaluate MRGesture in the context of my app. I see this was included in his docs. My bad.

  • FactoryOptimizrFactoryOptimizr USUniversity ✭✭

    Hi, @MichaelRumpler. I came across something odd as I was testing MR.Gestures that I thought you might want to be aware of. It appears that in the Android environment, the on-screen sizing of Buttons enhanced with MR.Gestures is different than normal Xamarin Forms buttons. MR.Gestures.Buttons are appear larger, given the same size parameters. The first of the two images below shows a set of five standard Xamarin Forms buttons in a StackLayout. The second image shows the same five buttons with the third button as a MR.Gestures.Button. Again, this appears to happen ONLY in the Android environment.

  • FactoryOptimizrFactoryOptimizr USUniversity ✭✭

    Hello, again, @MichaelRumpler. One more thing I've found -- this time an anomaly in the iOS environment. I added MR.Gestures enhancement to a ContentPage in order to enable the "Down" event to capture page-level coordinates for tap events. Interestingly, this seems to have disabled Click events for all the normal Xamarin Forms Buttons on the page. Remove MR.Gestures from the ContentPage and the Click events fire as expected. I've attached a simple test app that shows the problem. Again, this appears to happen ONLY in the iOS environment.

  • MagnusWallonMagnusWallon USMember ✭✭✭
    edited April 2017

    Hi @MichaelRumpler, do you have any smart Idea on how to start pinching from the fingers touches the element and not from center. Tried to move the anchorpoint but don't get it to work that well.

    My implementation looks like this(it's a grid because I'm going to stack stuff on top of each other later):


        <mr:StackLayout x:Name="stMapHolder" Panning="Handle_Panning" Pinching="Handle_Pinching">
            <mr:Grid x:Name="mapHolder">
                <Image Source="map2.jpg"/>
        <Label x:Name="txt" Text="MyTExt" HorizontalOptions="Center" /> 
    void Handle_Pinching(object sender, MR.Gestures.PinchEventArgs e)
                var anchX = e.Center.X;
                var anchY = e.Center.Y;
                mapHolder.AnchorX = anchX/mapHolder.Width;
                mapHolder.AnchorY = anchY/mapHolder.Height;
                var newScale = mapHolder.Scale * e.DeltaScale;
                mapHolder.Scale = Math.Min(5, Math.Max(0.1, newScale));
                txt.Text = "StackHolder Width:"+stMapHolder.Width+", anchX:"+anchX;

    One strange thing is that if I read the print out in the "txt" label I get "StackHolder Width:2999, anchX:390" just when I start pinching at the very end of the image/grid and not around 2900 as I would expect.

    Hope you or someone else can help.

  • MagnusWallonMagnusWallon USMember ✭✭✭

    Hi again, saw the problem just after I posted, if I changed the handler to work with the actual stacklayout instead it works.

    void Handle_Pinching(object sender, MR.Gestures.PinchEventArgs e)
                anchX = e.Center.X;
                anchY = e.Center.Y;
                stMapHolder.AnchorX = anchX/stMapHolder.Width;
                stMapHolder.AnchorY = anchY/stMapHolder.Height;
                var newScale = stMapHolder.Scale * e.DeltaScale;
                stMapHolder.Scale = Math.Min(5, Math.Max(0.1, newScale));
                txt.Text = "StackHolder Width:"+stMapHolder.Width+", anchX:"+anchX;

    Only problem now is that it "flickers" pretty much and I guess that is because I update the anchor point all the time, is there an event that get raised when I stop pinching? in that case I can put a boolean in as a flag so it only updates that point each time I start.


  • MichaelRumplerMichaelRumpler ATMember ✭✭✭✭✭

    You should not manipulate the container on which you handle the Pinching event, but only a child. See this FAQ.

    After Pinching it raises Pinched.

    In my GestureSample.ViewModels.TransformViewModel I have these lines:

    protected void SetAnchor(Point center)
        // in AnchorX/Y 0.0 means the top left corner and 1.0 means the bottom right
        // unfortunately I don't know how to calculate this correct if Translation, Scale and Rotation is used

    So, sorry, I don't know it either. ;)
    It should be possible with some simple matrix algebra, but I'm too long out of school and I forgot how that works.

  • MagnusWallonMagnusWallon USMember ✭✭✭
    edited April 2017

    Hi again, it wasn't the continues updates of the anchorpoint that I first thought, I was an easy fix wit the Up event but it still flickers alot. Is there a problem with putting the scaling directly on the StackLayout as I did now?


  • MagnusWallonMagnusWallon USMember ✭✭✭
    edited April 2017

    Hi again @MichaelRumpler, I was afraid that was the problem, have to find some other way then. But do you know why I get so strange values on e.Center.X as I was getting in my first example, the handler has the width of 2999 of the stacklayout but the only gives me around 400 at the furthest right side?

  • MichaelRumplerMichaelRumpler ATMember ✭✭✭✭✭

    @MagnusWallon No, sorry. But I'd rather question a width of 2999 than 400. Or are you doing that on a 4K display?

  • MagnusWallonMagnusWallon USMember ✭✭✭

    Hi again @MichaelRumpler, the 2999 is actually correct, that's the width of the image("map2.jpg") that should be scrolled and zoomed.


  • TonyDTonyD USMember ✭✭✭

    @MichaelRumpler we've had this crash appear a few times over the past month (since 1.4.1 I think). Can you check if it can be fixed or caught?

    System.InvalidOperationExceptionCollection was modified; enumeration operation may not execute.
    System.ThrowHelper.ThrowInvalidOperationException(ExceptionResource resource)<5887ac32cec44cc8aff7f904e4b9148b>:0
    System.Collections.Generic.Dictionary<TKey, TValue>.ValueCollection.Enumerator.MoveNext()<5887ac32cec44cc8aff7f904e4b9148b>:0
    System.Linq.Enumerable.WhereSelectEnumerableIterator<TSource, TResult>.MoveNext()<8299041aa6a24e5ea776cac83bd6e2d3>:0
    System.Linq.Buffer.Buffer(IEnumerable source)<8299041aa6a24e5ea776cac83bd6e2d3>:0
    System.Linq.Enumerable.ToArray(IEnumerable source)<8299041aa6a24e5ea776cac83bd6e2d3>:0
    MR.Gestures.Android.EventArgs.AndroidEventArgsHelper.GetTouches(IEnumerable touches):0
    MR.Gestures.Android.EventArgs.AndroidLongPressEventArgs.AndroidLongPressEventArgs(IEnumerable touches, long duration, View view)
    MR.Gestures.Android.TapGestureListener.onLongPressing(IEnumerable touches, long duration)
    at MR.Gestures.Android.TapGestureDetector+<b__9_0>d.MoveNext () [0x000d6] in

  • BradSmelster.5783BradSmelster.5783 USMember ✭✭

    Hi.. trying to run your samples.. But get this.. any ideas? thx

    2017-05-12 08:12:36.368 GestureSampleiOS[2336:37222] error: Xamarin.Forms.ConstraintExpression doesn't implement interface Xamarin.Forms.Xaml.IMarkupExtension<Xamarin.Forms.Constraint>
    2017-05-12 08:12:36.369 GestureSampleiOS[2336:37222] critical: Stacktrace:

    2017-05-12 08:12:36.369 GestureSampleiOS[2336:37222] critical: at <0xffffffff>
    2017-05-12 08:12:36.369 GestureSampleiOS[2336:37222] critical: at GestureSample.Views.PickerXaml.InitializeComponent () [0x00045] in C:\Temp\GestureSample-master\GestureSample-master\GestureSample\GestureSample\obj\Debug\GestureSample.Views.PickerXaml.xaml.g.cs:34
    2017-05-12 08:12:36.370 GestureSampleiOS[2336:37222] critical: at GestureSample.Views.PickerXaml..ctor () [0x00008] in C:\Temp\GestureSample-master\GestureSample-master\GestureSample\GestureSample\Views\PickerXaml.xaml.cs:12
    2017-05-12 08:12:36.370 GestureSampleiOS[2336:37222] critical: at GestureSample.Views.MainPage/d__1.MoveNext () [0x0140f] in C:\Temp\GestureSample-master\GestureSample-master\GestureSample\GestureSample\Views\MainPage.xaml.cs:136
    2017-05-12 08:12:36.370 GestureSampleiOS[2336:37222] critical: at System.Runtime.CompilerServices.AsyncVoidMethodBuilder.Start (TStateMachine_REF&) [0x0002c] in /Library/Frameworks/Xamarin.iOS.framework/Versions/
    2017-05-12 08:12:36.370 GestureSampleiOS[2336:37222] critical: at GestureSample.Views.MainPage.ListItem_Tapped (object,Xamarin.Forms.ItemTappedEventArgs) [0x00038] in <913831e7f86949ebb48cc785fb4544cd>:0
    2017-05-12 08:12:36.371 GestureSampleiOS[2336:37222] critical: at Xamarin.Forms.ListView.NotifyRowTapped (int,int,Xamarin.Forms.Cell) [0x00060] in C:\BuildAgent2\work\aad494dc9bc9783\Xamarin.Forms.Core\ListView.cs:390
    -05-12 08:12:36.371 GestureSampleiOS[2336:37222] critical: at Xamarin.Forms.ListView.Xamarin.Forms.IListViewController.NotifyRowTapped (int,int,Xamarin.Forms.Cell) [0x00000] in C:\BuildAgent2\work\aad494dc9bc9783\Xamarin.Forms.Core\ListView.cs:413
    2017-05-12 08:12:36.371 GestureSampleiOS[2336:37222] critical: at Xamarin.Forms.Platform.iOS.ListViewRenderer/ListViewDataSource.RowSelected (UIKit.UITableView,Foundation.NSIndexPath) [0x00047] in C:\BuildAgent2\work\aad494dc9bc9783\Xamarin.Forms.Platform.iOS\Renderers\ListViewRenderer.cs:864
    2017-05-12 08:12:36.371 GestureSampleiOS[2336:37222] critical: at (wrapper runtime-invoke) .runtime_invoke_void__this___object_object (object,intptr,intptr,intptr) [0x0005b] in :0
    2017-05-12 08:12:36.372 GestureSampleiOS[2336:37222] critical: at <0xffffffff>
    2017-05-12 08:12:36.372 GestureSampleiOS[2336:37222] critical: at (wrapper managed-to-native) UIKit.UIApplication.UIApplicationMain (int,string[],intptr,intptr)
    2017-05-12 08:12:36.372 GestureSampleiOS[2336:37222] critical: at UIKit.UIApplication.Main (string[],intptr,intptr) [0x00005] in /Users/builder/data/lanes/4691/675645b0/source/xamarin-macios/src/UIKit/UIApplication.cs:79
    2017-05-12 08:12:36.372 GestureSampleiOS[2336:37222] critical: at UIKit.UIApplication.Main (string[],string,string) [0x00038] in /Users/builder/data/lanes/4691/675645b0/source/xamarin-macios/src/UIKit/UIApplication.cs:63
    2017-05-12 08:12:36.373 GestureSampleiOS[2336:37222] critical: at GestureSample.iOS.Application.Main (string[]) [0x00001] in C:\Temp\GestureSample-master\GestureSample-master\GestureSample\GestureSample.iOS\Main.cs:17
    2017-05-12 08:12:36.373 GestureSampleiOS[2336:37222] critical: at (wrapper runtime-invoke) .runtime_invoke_void_object (object,intptr,intptr,intptr) [0x00051] in <3e4e00a0c6c14172ab094c4e37156899>:0
    2017-05-12 08:12:36.373 GestureSampleiOS[2336:37222] critical:
    Native stacktrace:
    2017-05-12 08:12:36.374 GestureSampleiOS[2336:37222] critical: 0 GestureSampleiOS 0x001cd48d mono_handle_native_crash + 269
    2017-05-12 08:12:36.374 GestureSampleiOS[2336:37222] critical: 1 GestureSampleiOS 0x001d6cd9 sigabrt_signal_handler + 153
    2017-05-12 08:12:36.374 GestureSampleiOS[2336:37222] critical: 2 libsystem_platform.dylib 0x0c61ae5b _sigtramp + 43
    2017-05-12 08:12:36.375 GestureSampleiOS[2336:37222] critical: 3 ??? 0xffffffff 0x0 + 4294967295

  • ArtArt USMember ✭✭

    is it possible to add application level (global) gestures?

  • BradSmelster.5783BradSmelster.5783 USMember ✭✭

    Hi.. Any idea why the Command will not fire on the Picker? I have tried everything. I'm using your exact sample code
    <mr:Picker x:Name="Picker1"
    Title="Picker 1"
    Grid.Row="0" Grid.Column="1"

                    DownCommand="{Binding DownCommand}"
                    UpCommand="{Binding UpCommand}"
                    TappingCommand="{Binding TappingCommand}"
                    TappedCommand="{Binding TappedCommand}"
                    DoubleTappedCommand="{Binding DoubleTappedCommand}"
                    LongPressingCommand="{Binding LongPressingCommand}"
                    LongPressedCommand="{Binding LongPressedCommand}"
                    PanningCommand="{Binding PanningCommand}"
                    PannedCommand="{Binding PannedCommand}"
                    SwipedCommand="{Binding SwipedCommand}"
                    PinchingCommand="{Binding PinchingCommand}"
                    PinchedCommand="{Binding PinchedCommand}"
                    RotatingCommand="{Binding RotatingCommand}"
                    RotatedCommand="{Binding RotatedCommand}"


  • Rohit_ArnavRohit_Arnav USMember ✭✭
    edited May 2017

    I need to move all the red bordered grid inside the main grid and also they can overlap or can be placed anywhere on the half of the height of the content page. is it possible to move all the red bordered grid separately in MR gesture?

    main concern is about moving the grids inside main grid. if it is possible then i am ready to get the key please help!

  • MichaelRumplerMichaelRumpler ATMember ✭✭✭✭✭

    I just released MR.Gestures 1.4.3-pre1.

    This version uses the new fast renderers for Android which were introduced in Xamarin.Forms 2.3.5. It therefore requires XF

    It should also fix the InvalidOperationException Collection was modified which @TonyD got sometimes in the LongPress event.

  • ChrisFouldsChrisFoulds GBMember ✭✭
    edited June 2017

    I just purchased this today and so far so good but I have a problem with buttons.
    I have a content view
    var dragViewGestures = new MR.Gestures.ContentView
    Content = layout,
    WidthRequest = Application.Current.MainPage.Width,
    HeightRequest = Application.Current.MainPage.Height

    This has panned attached.
    dragViewGestures.Panned += (sender, e) =>
    // code

    dragViewGestures.Panning += (sender, e) =>
    // code

    In that contentview I have buttons, these no longer work.
    I read this would be the case if I used the down event , but I don't

  • MichaelRumplerMichaelRumpler ATMember ✭✭✭✭✭

    You didn't say on which platform you tried this. At least iOS tries to be smarter than the developer and only raises some events if it thinks, that no other element handles them. This might be the problem here.

    Replace the Button with a Label or Image with a Tapped handler then it should work.

  • davelynchdavelynch USMember ✭✭

    I am trying to use the .Panned event. It works great in Android but not at all in iOS, Do I need to have a license in order to use it on iOS?

  • TonyDTonyD USMember ✭✭✭

    @MichaelRumpler are you able to compile a version which does not require 2.3.5 (and still has the crash fix above)?

    2.3.5 has a lot of issues right now so we won't be moving to it for at least a few months.

  • MichaelRumplerMichaelRumpler ATMember ✭✭✭✭✭
    edited June 2017

    I didn't try all events without license. As all properties of the EventArgs have their default values and additional events are only raised, if the fingers are moved by a significant value, Panning (Pinching and Rotating) will only be raised once. The same goes for Tapped (which will only be raised if NumberOfTaps == 1) and DoubleTapped. I can imagine that Panned is not raised due to a similar reason. But if you need Panned, then you also need to know, how far and in which direction the finger was moved, so you need a license anyway.

    I don't think that I can submit a version to NuGet after I submitted a higher version. But I could build something and upload to GitHub. But I don't have time for this today. Hopefully tomorrow.

  • MichaelRumplerMichaelRumpler ATMember ✭✭✭✭✭


    It actually was possible to publish MR.Gestures to NuGet. So this fixes the "Collection was modified" exception when raising LongPressing on Android without the need to update to XF 2.3.5-pre.

  • TonyDTonyD USMember ✭✭✭

    thanks @MichaelRumpler I'll update to it, hopefully that crash goes away.

  • davelynchdavelynch USMember ✭✭
    edited July 2017

    I have bought a licenses the events now work on iOS! Although I've found that when applying the Panned event to a slider it only fires the firs time you slide, any time after that it doesn't. any ideas?

  • MichaelRumplerMichaelRumpler ATMember ✭✭✭✭✭


    Apple always strives to help the developer so they do what they think is best. The UISlider from iOS "optimizes" the gestures so that it consumes them and doesn't forward them to any gesture recognizers. This is also documented on

    The checkmark is yellow for the Slider on iOS. This means it does not fully work. Hover over it to see details.

    To work around this issue you can make your own image which can be drag&dropped and use that instead of the Slider.

  • MichaelRumplerMichaelRumpler ATMember ✭✭✭✭✭

    Xamarin introduced a breaking change in XF as I wrote in the release thread. Therefore MR.Gestures does not work with that version. I suggest you stay on XF until they release 2.4.0-pre2. They are aware of the problem and already have a fix for it.

    When they release 2.4.0-pre2, then you can use MR.Gestures with it. MR.Gestures 1.4.3-pre1 will not work anymore because they changed the fast renderers to be internal. But I already used those in 1.4.3-pre1.

  • RyanMorrisRyanMorris USMember
    edited August 2017

    I'm having issues with using panning to modify TranslationY. I have a content view inside a relative layout. When I drag the view up and down it jump up and down extremely quickly. The blue area has the Panning event and when dragging it the contentview TranslationY tends to jump back and forth between where finger is and where it was a few ms before. I also cant get it to keep up with finger movement. So when you start the blue header stays under your finger but if you move quickly or for an extended period your finger ends up a few inches above the blue header. Hard to tell bc of the gif frame rate but I forked the sample repo and have code at Github. Problem occurs with a release build on nexus 6p, so not just debug in emulator.

  • RyanMorrisRyanMorris USMember

    @MichaelRumpler maybe that wasn't a great example. In our real app underneath the draggable window, we have a map view that fills the screen. I was trying to prevent the user panning the map area from triggering movement of the window, so my goal was to require the panning to begin on the header of the window.

    My only other idea would be to put the Panning event on a container and the an Up/Down on the header that sets a variable such as 'AllowMoveInfoWindow', do you have any thoughts on this?

  • aj-jaaj-ja IEMember

    Hi, any advise on UWP app with toolbar? When I click on toolbar item, the tap event on the element that is behind the toolbar fires too.

    <?xml version="1.0" encoding="utf-8" ?>

        <ScrollView VerticalOptions="FillAndExpand">
            <AbsoluteLayout HorizontalOptions="FillAndExpand" VerticalOptions="Start">
                <BoxView Color="Blue" AbsoluteLayout.LayoutBounds="0,0,1,500"
                        AbsoluteLayout.LayoutFlags="WidthProportional" />
                <mr:BoxView Color="Green" AbsoluteLayout.LayoutBounds="0,700,1,500"
                        AbsoluteLayout.LayoutFlags="WidthProportional" Tapped="OnTapGestureRecognizerTapped">
            <ToolbarItem Name="MenuItem1" Order="Primary" Text="Item 1" Priority="0" Clicked="ToolbarTapped" />

    using System;
    using Xamarin.Forms;

    namespace App1
        public partial class MainPage : ContentPage
            public MainPage()
            async void OnTapGestureRecognizerTapped(object sender, EventArgs args)
                await DisplayAlert("Test", "Green box tapped!", "OK");
            async private void ToolbarTapped(object sender, EventArgs e)
                await DisplayAlert("Test2", "Toolbar item tapped", "OK");

    and making sure that in App.xaml.cs MainPage is wrapped in NavigationPage
    MainPage = new NavigationPage(new App1.MainPage());
    so that toolbar is visible.

    When I scroll so that Green box is behind the toolbar and click on Toolbar item I get both Alerts - for box itself and toolbar.
    When I scroll so that Blue box or blank space is behind the toolbar I get only alert for toolbar.

    Expected that in all cases when I click on Toolbar I get only Toolbar alert.


Sign In or Register to comment.