Search code examples
xamlxamarinswipe-gesturexamarin.forms

Xamrin Forms : Swipe to delete(gesture) in ListView


I want to implement the swipe to delete functionality in Xamrin Forms, for which i have tried the following.

  1. Wrote a custom renderer for the list view and in the "OnElementChanged" of the renderer am able to access the binded command to the "CustomListView" and am able to add this command to the Swipe Gesture as added below.

       swipeGestureRecognizer = new UISwipeGestureRecognizer (() => {
            if (command == null) {
                Console.WriteLine ("No command set");
                return;}
    
            command.Execute (null);
        });
    

However i am having trouble in accessing the specific row(swiped row), so that i could make a button visible/hidden on the swiped row in the list view. Please could you recommend a way to implement the same?


Solution

  • You could do something like this:

        protected override void OnElementChanged (ElementChangedEventArgs<ListView> e)
        {
            base.OnElementChanged (e);
            var swipeDelegate = new SwipeRecogniserDelegate ();
            swipeGestureRecognizer = new UISwipeGestureRecognizer {
                Direction = UISwipeGestureRecognizerDirection.Left,
                Delegate = swipeDelegate
            };
            swipeGestureRecognizer.AddTarget (o => {
                var startPoint = swipeDelegate.GetStartPoint ();
                Console.WriteLine (startPoint);
                var indexPath = this.Control.IndexPathForRowAtPoint(startPoint);
                if(listView.SwipeCommand != null) {
                    listView.SwipeCommand.Execute(indexPath.Row);
                }
            });
            this.Control.AddGestureRecognizer (swipeGestureRecognizer);
            this.listView = (SwipableListView)this.Element;
        }
    

    The key is SwipeRecogniserDelegate. its implemented like so:

    public class SwipeRecogniserDelegate : UIGestureRecognizerDelegate
    {
        PointF startPoint;
    
        public override bool ShouldReceiveTouch (UIGestureRecognizer recognizer, UITouch touch)
        {
            return true;
        }
    
        public override bool ShouldBegin (UIGestureRecognizer recognizer)
        {
            var swipeGesture = ((UISwipeGestureRecognizer)recognizer);
            this.startPoint = swipeGesture.LocationOfTouch (0, swipeGesture.View);
            return true;
        }
    
        public PointF GetStartPoint ()
        {
            return startPoint;
        }
    }