MR.Gestures handles ALL touch gestures

1235710

Posts

  • MichaelRumplerMichaelRumpler Michael Rumpler ATMember ✭✭✭✭

    MR.Gestures 1.3.0 has been released.

    It fixes the bug @BastiBrauning and @LuisAplito had with the Tapping/Tapped event on Android.

    @BastiBrauning A ListView works fine in the GestureSample on UWP. Please send a repro project.

  • LuisAplitoLuisAplito Luis Apólito DOMember ✭✭

    Great news @MichaelRumpler , I just tested and its working great. However, it seems thats also happening with the "Up" Gesture, because I change a label's background color when "Down" gesture happens, and change it back again when "Up" gesture happens. However, when I click on the label and scroll (its inside a scrollview) up or down, and then release, the background color doesn't changes back.

    It used to work well on Android and still works great on iOS, maybe is the same bug on "Up" gesture?

  • MichaelRumplerMichaelRumpler Michael Rumpler ATMember ✭✭✭✭

    The problem with Tapping was in my TapGestureRecognizer which I introduced in 1.2.5. But Down/Up did not change at all. I'll have a look at it.

  • BastiBrauningBastiBrauning Basti Brauning USMember

    Sorry the UWP exception was a fault on my end (hidden well in the stacktrace...)

    The android stuff works great on my end, many thanks for the update!

    Another UWP thing: Are the tapping/tapped events not cosumed by MR.Gestures? When I have a MR.Gesture.Label on a ViewCell the Tapping command is executed and additionally the "ItemSelected" of the ListView.

  • MichaelRumplerMichaelRumpler Michael Rumpler ATMember ✭✭✭✭
    edited December 2015

    I try not to consume anything at all so that the native functionality keeps working. So if Tapping and ItemSelected work at the same time, this is actually good.

    Unfortunately on Android ItemSelected does not work on MR.Gestures cells. I filed bug #36832 because of that. It is enough to add an empty event handler to the Touch event and the native touch handling like animation, ItemTapped and ItemSelected don't work anymore. But just handling an event should not change anything.

  • BastiBrauningBastiBrauning Basti Brauning USMember
    edited December 2015

    Okay I see.

    Basically I want the whole Cell to be selectable by a user to navigate to a Detail view. But also some parts of the cell should navigate the user to a different page.

    So the behaviour I try to achieve does work fine on Android/iOS currently because ItemSelected is not fired when clicking on an Image in the cell. But on UWP I'm struggeling because ItemSelected for the cell and Tapping for the Image in the Cell are both fired.

    I slightly modified your sample code http://pastebin.com/2mGQTjkp to demonstrate my UWP problem

    So how should I know that the user clicked on the label and not on any other part of the cell, because both events are fired? So currently my UWP app pushes two new pages on the stack.

  • MichaelRumplerMichaelRumpler Michael Rumpler ATMember ✭✭✭✭

    The only thing which comes to my mind is, that you wait a few milliseconds in ItemSelected and only do your stuff when no Tapping comes from the other elements.

  • MichaelRumplerMichaelRumpler Michael Rumpler ATMember ✭✭✭✭

    @LuisAplito When you scroll, then Android only sends a Cancel when your finger moves out of the original position of the element you're watching. Unfortunately it does not send anything to that element when the finger is actually removed. I didn't use the Cancel for the Down/Up gestures because I thought, it won't be of any use. I changed that now.
    When you drag your finger out of the element you're watching, then you now get a Up event with Cancelled set to true.
    Furthermore you can handle Down/Up on the ScrollView. These events will be raised as long as your finger remains inside the ScrollView. I tested that with TextCells inside of a ListView, but it's the same principle.

    Some people also reported NullReferenceExceptions on initializing the iOS app. It turns out that Xamarin Studio now writes the app name to CFBundleName in the info.plist file instead of CFBundleDisplayName which they used before. I read both values now when I check the LicenseKey.

    The new version 1.3.1 has been released to NuGet.

  • RodyRody Rodolfo De Los Santos USMember ✭✭

    @LuisAplito Try the new version that @MichaelRumpler recently released (1.3.1)

    It fixed the same issue I was having on Android with the "Up" Gesture being consumed by the listview when scrolling or swiping.

  • LuisAplitoLuisAplito Luis Apólito DOMember ✭✭

    Yeah it does @Rody, thanks @MichaelRumpler for fixing this, works like a charm!

  • DanielZolnjanDanielZolnjan Daniel Zolnjan USMember
    edited January 2016

    Panning event within ScrollView stops firing in Android, but works in iOS.

    <ScrollView Orientation="Horizontal"> <mr:BoxView WidthRequest="50" HeightRequest="50" Color="Red" Panning="OnPanning" Panned="OnPanned"> </mr:BoxView> <mr:BoxView WidthRequest="50" HeightRequest="50" Color="Red" Panning="OnPanning" Panned="OnPanned"> </mr:BoxView> <mr:BoxView WidthRequest="50" HeightRequest="50" Color="Red" Panning="OnPanning" Panned="OnPanned"> </mr:BoxView> <mr:BoxView WidthRequest="50" HeightRequest="50" Color="Red" Panning="OnPanning" Panned="OnPanned"> </mr:BoxView> <mr:BoxView WidthRequest="50" HeightRequest="50" Color="Red" Panning="OnPanning" Panned="OnPanned"> </mr:BoxView> <mr:BoxView WidthRequest="50" HeightRequest="50" Color="Red" Panning="OnPanning" Panned="OnPanned"> </mr:BoxView> <mr:BoxView WidthRequest="50" HeightRequest="50" Color="Red" Panning="OnPanning" Panned="OnPanned"> </mr:BoxView> <mr:BoxView WidthRequest="50" HeightRequest="50" Color="Red" Panning="OnPanning" Panned="OnPanned"> </mr:BoxView> <mr:BoxView WidthRequest="50" HeightRequest="50" Color="Red" Panning="OnPanning" Panned="OnPanned"> </mr:BoxView> </ScrollView>

    OnPanning will keep firing only if finger is moved up or down (not activating horizontal scroll).
    As soon as you try moving finger left or right OnPanning stops firing and the final OnPanned is called.

    This however works on iOS. ScrollView will keep scrolling and OnPanning will keep firing until finger is raised.

    So is this limitation of Android platform or there is workaround with MR Gestures to make it work like on iOS.

  • MichaelRumplerMichaelRumpler Michael Rumpler ATMember ✭✭✭✭

    @DanielZolnjan This is how Android works. Also see my last comment a bit up on this page.

  • BrunoPasquini.7813BrunoPasquini.7813 Bruno Pasquini AGMember

    Hi, do you have an example of how to use this library for pitching and scrolling but using code and not xaml?

  • MichaelRumplerMichaelRumpler Michael Rumpler ATMember ✭✭✭✭

    @BrunoPasquini.7813
    In the GestureSample the ContentPageXaml uses pinch to zoom and pan to drag the image. In BoxViewCode you can find code which uses the MR.Gestures elements. There are also samples on my web page. The rest is simple data binding.

  • JKayJKay James Kennedy USMember ✭✭✭
    edited January 2016

    Has anyone ever tried to implement a swipe on a view which starts off the screen using MR.Gestures?

    i.e. for a Navigation drawer?

    So touch down would not start on the view but you would be panning across the view and your starting X position would be equal to 0?

  • DirkWilhelmDirkWilhelm Dirk Wilhelm USMember ✭✭✭

    @MichaelRumpler I have a question regarding using your gestures within a MasterDetailPage.

    I have a detail page with a horizontal pan gestures. On Android i can open the master page with a swipe from the very left of the screen and i can also close the master page with a swipe from right to left. The panning gesture in the detail page also works fine and as expected.

    On iOS this does not work. The pan gesture in the detail page does not work, panning from left to right will always open the master page. To get the pan gesture in the detail page to work i have to disable the panning behavior of the MasterDetailPage with "IsGestureEnabledProperty = false".

    Is it possible to get it to work on iOS as it works on Android?

  • MichaelRumplerMichaelRumpler Michael Rumpler ATMember ✭✭✭✭

    @JKay I didn't try it, but you should be able to listen to Panning on the page and then just let the drawer follow your horizontal finger position until Panned. After that you can animate it to the open or closed position.

    @DirkWilhelm My pan handlers are overridden by the iOS UISplitViewController. Unfortunately I don't know how I could override that (and still keep the MasterDetailPage working).

  • JKayJKay James Kennedy USMember ✭✭✭

    @MichaelRumpler Thanks. Just implemented it as you said and seems to work really well.

    It doesn't register 0 as start position of the pan but I think I may try have a threshold. i.e. X < 50 and the acceleration. I'll play around with it today

  • GarryWhittaker.3919GarryWhittaker.3919 Garry Whittaker GBUniversity ✭✭

    @MichaelRumpler just implemented this in a project and it was a real 'life saver' thank you. Is it possible to add the information about Android scrollviews to your documentation - I wasted a while on trying to debug that behaviour.

    Many thanks
    Garry

  • BastiBrauningBastiBrauning Basti Brauning USMember

    With the latest Xamarin.Forms 2.1.0-pre2 I'm sometimes getting the following exception reported in Insights from users:

    System.ExceptionException from HRESULT: 0x88000FA8
    Raw
       at Windows.UI.Xaml.Media.VisualTreeHelper.FindElementsInHostCoordinates(Point intersectingPoint, UIElement subtree, Boolean includeAllElements)
       at MR.Gestures.UWP.UWPGestureHandler.OnPointerPressed(CoreWindow sender, PointerEventArgs ev)
    
  • MichaelRumplerMichaelRumpler Michael Rumpler ATMember ✭✭✭✭

    @GarryWhittaker.7482 What exactly do you mean?

    @BastiBrauning With older versions FindElementsInHostCoordinates sometimes returned no elements when the gesture started shortly after the view has been initialized, but I didn't get any exceptions. I'll test more with XF 2.1.0-pre2 and maybe surround it with a try/catch.

  • toSilencetoSilence Matthias Hacker USMember

    Hi,
    I'm just trying out your library.
    I use a ListView within a shared project. Its working great since I start to implement a custom view cell which is inherited from your MR.Gestures.ViewCell.
    In my custom view cell is only one label. If I run my app the down event for the view cell is never fired but for the label i can catch the event.
    Maybe I do sth wrong?

    Any help appreciated.

    Thx in advance

  • MichaelRumplerMichaelRumpler Michael Rumpler ATMember ✭✭✭✭

    @toSilence
    Does the Down event work on a ViewCell in the GestureSample for you?
    If your custom ViewCell also uses its custom renderer, then that renderer needs to inherit from MR.Gestures.platform.Renderers.ViewCellRenderer.
    If you do this on Windows, then the ListView must also be an MR.Gestures.ListView as there are no cell renderers on that platform. The functionality is built into the ListViewRenderer/TableViewRenderer.

  • toSilencetoSilence Matthias Hacker USMember

    @MichaelRumpler
    Yes the Down event is working.
    No I'm not using a custom renderer.
    I'm using it on Android. I will attach a file.
    Thx in advance

  • MichaelRumplerMichaelRumpler Michael Rumpler ATMember ✭✭✭✭

    @toSilence
    I debugged that. It seems like if the Label handles the gesture, then the ViewCell doesn't get it anymore. The native Touch handler for the cell is never called, so I also cannot raise the event.

    The strange thing is, that the Touch handlers of the surrounding ListView and ContentPage are called, but not that of the ViewCell. I have no idea why.
    It may be related to bug#36832. The repro project attached to that bug shows that simply adding a Touch handler to a ViewCell (or a Label inside) prevents the default handling of that tap.

    On iOS and Windows (tested in UWP) the Down handlers of all Label, ViewCell, ListView and ContentPage are called.

    But it's a tough call anyway. @DominikWeber recently complained about a bug because the Down handler of a Grid is called although the touch was actually on a BoxView within the Grid which also handles the event. That raises the question: when should an event be raised for overlapping elements?

  • toSilencetoSilence Matthias Hacker USMember

    @MichaelRumpler
    Sorry I was busy with another project.
    Ok I checked the bug report it seems to be related with my problem.

    Maybe this is not working for any case but:
    I personally think an event should be raised anytime and if someone want to stop the event from bubbling up could set a handled property to true. I don't know if this implementation is possible for your library.

    Nevertheless I have to solve this problem.

    Can you imagine another solution with your library?
    Maybe I can overwrite some behaviour to solve just my case?

    Thank you advance

  • MichaelRumplerMichaelRumpler Michael Rumpler ATMember ✭✭✭✭

    @toSilence The Handled property is there since the beginning and it was planned to do exactly that. But unfortunately Android has a very different notion of what handled means and so I could never implement it so that it works cross platform. I'd have to put much more effort in it which would also raise the price of MR.Gestures.

    You could just put a ContentView as main element of your ViewCell and handle the gestures on that. This shouldn't be any different from handling them on the ViewCell itself.

  • HenricBerglfHenricBerglf Henric Berglöf SEMember ✭✭
    edited February 2016

    @MichaelRumpler
    Hi
    I really need som drag and drop functionality in a forms app and maybe this is the easiest way to get that.
    Will it be possible to have a few buttons to be dragged and dropped into some pre-defined targets,
    i.e. letter tiles into a game grid? After one tile is dropped that area should no longer be valid drop target.
    Thanks,
    H

  • MichaelRumplerMichaelRumpler Michael Rumpler ATMember ✭✭✭✭

    @HenricBerglf Sure. Check out the GestureSample. It lets you drag some elements around.
    You'll get all the Panning and Panned events. The business logic - which element can be dragged and dropped - has to come from you.

  • BastiBrauningBastiBrauning Basti Brauning USMember
    edited February 2016

    I experience another UWP error when popping pages:

    An exception of type 'System.ArgumentNullException' occurred in mscorlib.ni.dll but was not handled in user code
    
    Additional information: Value cannot be null.
           at System.Collections.Generic.Dictionary`2.FindEntry(TKey key)
       at MR.Gestures.UWP.UWPGestureHandler.RemoveInstance(IGestureAwareControl element)
       at MR.Gestures.UWP.Renderers.ListViewRenderer.Dispose(Boolean disposing)
       at Xamarin.Forms.Platform.UWP.VisualElementRenderer`2.Dispose()
       at Xamarin.Forms.Platform.UWP.VisualElementExtensions.Cleanup(VisualElement self)
       at Xamarin.Forms.Platform.UWP.NavigationPageRenderer.SetPage(Page page, Boolean isAnimated, Boolean isPopping)
       at Xamarin.Forms.Platform.UWP.NavigationPageRenderer.OnPopRequested(Object sender, NavigationRequestedEventArgs e)
       at Xamarin.Forms.NavigationPage.<PopAsyncInner>d__69.MoveNext()
    
  • MichaelRumplerMichaelRumpler Michael Rumpler ATMember ✭✭✭✭

    @BastiBrauning When does this happen? Can you send me a repro project please.

  • BastiBrauningBastiBrauning Basti Brauning USMember

    @MichaelRumpler I'm not sure how to pack it into a repro project, since I'm currently unable to find out what is causing this (sometimes occurring) error.

    But I have another question, is it possible to disable all these debug printlines in MR.Gestures? On my release build I noticed the device log on android to be full of MR.Gestures output:

    02-19 14:02:07.860 13720 13720 I mono-stdout: HandleMotionEvent: Action: Down on MyRenderer, Pointer 0: 586/1301
    02-19 14:02:07.863 13720 13720 I mono-stdout: HandleMotionEvent: Action: Down on MyRenderer, Pointer 0: 406/20
    02-19 14:02:07.866 13720 13720 I mono-stdout: HandleMotionEvent: Action: Down on MyRenderer, Pointer 0: 406/20
    02-19 14:02:07.873 13720 13720 I mono-stdout: HandleMotionEvent: Action: Move on MyRenderer, Pointer 0: 587/1291
    02-19 14:02:07.873 13720 13720 I mono-stdout: HandleMotionEvent: Action: Move on MyRenderer, Pointer 0: 407/10
    02-19 14:02:07.873 13720 13720 I mono-stdout: HandleMotionEvent: Action: Move on MyRenderer, Pointer 0: 407/10
    02-19 14:02:07.889 13720 13720 I mono-stdout: HandleMotionEvent: Action: Move on MyRenderer, Pointer 0: 601/1221
    02-19 14:02:07.890 13720 13720 I mono-stdout: HandleMotionEvent: Action: Cancel on MyRenderer, Pointer 0: 601/1221
    02-19 14:02:07.890 13720 13720 I mono-stdout: HandleMotionEvent: Action: Cancel on MyRenderer, Pointer 0: 601/1221
    02-19 14:02:07.906 13720 13720 I mono-stdout: HandleMotionEvent: Action: Move on MyRenderer, Pointer 0: 631/1061
    02-19 14:02:07.923 13720 13720 I mono-stdout: HandleMotionEvent: Action: Move on MyRenderer, Pointer 0: 668/820
    
  • MichaelRumplerMichaelRumpler Michael Rumpler ATMember ✭✭✭✭

    Oops, those slipped through. They should not be included in the release version of course.
    I disabled the debug statements in the source. They will be gone in the next version.

  • toSilencetoSilence Matthias Hacker USMember

    @MichaelRumpler

    We bought your library and implemented it in our project.
    It works fine. I have just a detail question.
    The swipe left and swipe right on a ListView in Android seems to trigger only if my gesture is horizontal straight.

    Is there a config or a setting which we can set to enable a not so 'correct' detection?
    It is all about some degrees.

    Thank you in advance.

    Best Regards

  • MichaelRumplerMichaelRumpler Michael Rumpler ATMember ✭✭✭✭

    @toSilence When you handle Swiped on a ListView, then it also raises on swipe up/down.
    When you handle it on a cell however, then that cell will be scrolled out of the way and/or your finger will be moved off the cell where it started.
    You could handle Down on a cell and Swiped and Up on the ListView. Then you see which cell it is in Down and you can handle the Swiped and reset the gesture on Up.

  • BastiBrauningBastiBrauning Basti Brauning USMember

    @MichaelRumpler
    As I stated earlier I experience crashes on UWP when popping pages with listviews, this is also happening for WinRT.

       at System.Collections.Generic.Dictionary`2.FindEntry(TKey key)
       at MR.Gestures.WinRT.WinRTGestureHandler.RemoveInstance(IGestureAwareControl element)
       at MR.Gestures.WinRT.Renderers.ListViewRenderer.Dispose(Boolean disposing)
       at Xamarin.Forms.Platform.WinRT.VisualElementRenderer`2.Dispose()
       at Xamarin.Forms.Platform.WinRT.VisualElementExtensions.Cleanup(VisualElement self)
       at Xamarin.Forms.Platform.WinRT.NavigationPageRenderer.SetPage(Page page, Boolean isAnimated, Boolean isPopping)
       at Xamarin.Forms.Platform.WinRT.NavigationPageRenderer.OnPopRequested(Object sender, NavigationRequestedEventArgs e)
       at Xamarin.Forms.NavigationPage.<PopAsyncInner>d__69.MoveNext()
    --- End of stack trace from previous location where exception was thrown ---
       at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
       at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
       at Xamarin.Forms.NavigationPage.<PopAsync>d__68.MoveNext()
    

    I don't know why but Dispose is sometimes called when "this.Element" is null.

    So when the MR.Gestures.ListViewRenderer tries to remove touch listeners it'll crash in WinRTGestureHandler.RemoveInstance(element):

    when checking "WinRTGestureHandler.allGestureHandlers.ContainsKey(element)" and "element" is null it will result in a exception 'System.ArgumentNullException' occurred Value cannot be null.Parameter name: key

    So a fix might be checking the element for null before calling ContainsKey, e.g.

        public static void RemoveInstance(IGestureAwareControl element)
        {
          if (element == null || !WinRTGestureHandler.allGestureHandlers.ContainsKey(element))
            return;
    
        ....
        }
    
  • MichaelRumplerMichaelRumpler Michael Rumpler ATMember ✭✭✭✭

    @BastiBrauning I only saw those calls to Dispose after this.Element was set to null on UWP and there I also already had the null check. However I added that null check on all platforms now.

    As I already stated earlier I also disabled the debug statements.

    The new version 1.3.2 was released some minutes ago.

  • toSilencetoSilence Matthias Hacker USMember

    @MichaelRumpler
    In the ListView is a collection:
    HashSet CellsToDispose { get; }

    I'm using it in my code because it contains the cells of the current ListView.

    I know its not correct and I want to improve my code:
    So are there any other items which contains all the cells of the ListView?
    How can I manage/delete the items of CellsToDispose?
    Where are the items added to CellsToDispose?
    (because maybe I can create and mange my own collection)

    Thank you in advance.

    Best Regards

  • MichaelRumplerMichaelRumpler Michael Rumpler ATMember ✭✭✭✭

    @toSilence That property is not intended to be used by you. It just helps me to maintain a list of the visible cells. It does not hold all cells in the list, but only the visible ones.

  • toSilencetoSilence Matthias Hacker USMember

    @MichaelRumpler

    Yes, I know it's not intended, but until now my only solution to get cells out of a ListView. Which is very important for us.
    Maybe you can imagine an 'official' collection of cells for further releases?

    I need this implementation for further/improved swipe detections.
    It's very powerful.

    Thank you in advance.

    Best Regards.

Sign In or Register to comment.