Xamarin UISwipeGestureRecognizer Renderer

In Xamarin.Forms, I want to be able to scroll left and right to navigate through the list of images. For now, I just want to be able to fire an event every time a swipe is detected.

child class to be used in the renderer:

public class LRMasterDetailPage : ContentView
{
}

      

I have a ContentPage that uses the LRM class like this:

    public class ImagePage : ContentPage 
    {

    public ImagePage(Photo photo)
        {
            _image = new WebImage
                {
                    Url = photo.Url,
                    Placeholder = "placeHolder2.png"
                };

            var imageView = new LRMasterDetailPage {
                Content = _image
            };

            this.Content = imageView;
           }
      }

      

This is my rendering:

    [assembly:ExportRenderer (typeof(LRMasterDetailPage), typeof(LRMDPRenderer))]
namespace Project.iOS
{
    public class LRMDPRenderer : ViewRenderer<LRMasterDetailPage,UIView>
    {
        UISwipeGestureRecognizer swipe;

        protected override void OnElementChanged (ElementChangedEventArgs<LRMasterDetailPage> e)
        {
            base.OnElementChanged (e);
            // Do someting else, init for example
            swipe = new UISwipeGestureRecognizer();
            this.AddGestureRecognizer (swipe);

            if (swipe.Direction == UISwipeGestureRecognizerDirection.Left) 
            {
                UpdateLeft ();
            }

            if (swipe.Direction == UISwipeGestureRecognizerDirection.Right) 
            {
                UpdateRight ();
            }
        }

        protected override void OnElementPropertyChanged (object sender, System.ComponentModel.PropertyChangedEventArgs e)
        {
            if (e.PropertyName == "Renderer")
                return;
            base.OnElementPropertyChanged (sender, e);

        }

        private void UpdateLeft(){
            // Insert view of DetailLeft element into subview
            // Add button to open Detail to parent navbar, if not yet there
            // Add gesture recognizer for left swipe
            Console.WriteLine ("Left swipe");

        }
        private void UpdateRight(){
            // same as for left, but flipped
            Console.WriteLine ("Right swipe");

        }
    }
}

      

When the ContentPage is displayed, a context event is fired, but nothing happens when I try to drag over the image. I'm assuming my logic on the renderer is wrong?

+3


source to share


1 answer


After a lot of pain and searching on the internet, I found a solution.

What you need to do is simple: declare and add a gesture in the renderer. Make sure you create a swipe gesture to the right and left, announcing your direction. from there, use a lambda to call the function you want to activate for a specific scroll:

Scroll gesture bookmark class.

public class LRMasterDetailPage : ContentView
    {

    }

      



An image page that contains one image at a time

public class ImagePage : ContentPage
{

    //view holding the image
    LRMasterDetailPage imageView;

    //collection of images using the photo.Url
    ObservableCollection<Image> images;

    //current image index
    int index = 0;

public ImagePage(){

       images = new ObservableCollection<Image> ();
       imageView = new LRMasterDetailPage {
            Content = this.images [index]
        };

        this.Content = imageView;
}

 //Subscribe to the swipeLeft and swipeRight message
  protected override void OnAppearing ()
    {
        base.OnAppearing ();

        MessagingCenter.Subscribe <string> (this,"LeftSwipe", (sender) => {

            //Do something
            if(index < images.Count-1){
                index++;
            }

            imageView.Content = this.images[index];


        });
        MessagingCenter.Subscribe <string> (this, "RightSwipe", (sender) => {

            //Do something
            if(index > 0){
                index--;
            }

            imageView.Content = this.images[index];


        });
   }

     protected override void OnDisappearing()
    {
        base.OnDisappearing();

        //this._image = null;

        images = null;

        MessagingCenter.Unsubscribe<string>(this,"LeftSwipe");
        MessagingCenter.Unsubscribe<string>(this, "RightSwipe");
        MessagingCenter.Unsubscribe<string>(this, "LongPress");

        //GC.Collect();
    }

}

      

Renderer for LRMasterDetailPage

    [assembly:ExportRenderer (typeof(LRMasterDetailPage), typeof(LRMDPRenderer))]
namespace Manager.iOS
{
    public class LRMDPRenderer : ViewRenderer<LRMasterDetailPage,UIView>
    {

        UILongPressGestureRecognizer longPressGestureRecognizer;
        UIPinchGestureRecognizer pinchGestureRecognizer;
        //UIPanGestureRecognizer panGestureRecognizer;
        UISwipeGestureRecognizer swipeRightGestureRecognizer;
        UISwipeGestureRecognizer swipeLeftGestureRecognizer;
        UIRotationGestureRecognizer rotationGestureRecognizer;

        protected override void OnElementChanged (ElementChangedEventArgs<LRMasterDetailPage> e)
        {
            base.OnElementChanged (e);

            longPressGestureRecognizer = new UILongPressGestureRecognizer (() => Console.WriteLine ("Long Press"));
            pinchGestureRecognizer = new UIPinchGestureRecognizer (() => Console.WriteLine ("Pinch"));
            //panGestureRecognizer = new UIPanGestureRecognizer (() => Console.WriteLine ("Pan"));

            swipeRightGestureRecognizer = new UISwipeGestureRecognizer ( () => UpdateRight()){Direction = UISwipeGestureRecognizerDirection.Right};
            swipeLeftGestureRecognizer = new UISwipeGestureRecognizer ( () => UpdateLeft()){Direction = UISwipeGestureRecognizerDirection.Left};
            rotationGestureRecognizer = new UIRotationGestureRecognizer (() => Console.WriteLine ("Rotation"));

            if (e.NewElement == null) {
                if (longPressGestureRecognizer != null) {
                    this.RemoveGestureRecognizer (longPressGestureRecognizer);
                }
                if (pinchGestureRecognizer != null) {
                    this.RemoveGestureRecognizer (pinchGestureRecognizer);
                }

                /*
                if (panGestureRecognizer != null) {
                    this.RemoveGestureRecognizer (panGestureRecognizer);
                }
                */

                if (swipeRightGestureRecognizer != null) {
                    this.RemoveGestureRecognizer (swipeRightGestureRecognizer);
                }
                if (swipeLeftGestureRecognizer != null) {
                    this.RemoveGestureRecognizer (swipeLeftGestureRecognizer);
                }

                if (rotationGestureRecognizer != null) {
                    this.RemoveGestureRecognizer (rotationGestureRecognizer);
                }
            }

            if (e.OldElement == null) {
                this.AddGestureRecognizer (longPressGestureRecognizer);
                this.AddGestureRecognizer (pinchGestureRecognizer);
                //this.AddGestureRecognizer (panGestureRecognizer);
                this.AddGestureRecognizer (swipeRightGestureRecognizer);
                this.AddGestureRecognizer (swipeLeftGestureRecognizer);
                this.AddGestureRecognizer (rotationGestureRecognizer);
            }
        }

        private void UpdateLeft(){
            MessagingCenter.Send ("Swiped to the left", "LeftSwipe");

        }
        private void UpdateRight(){
            // same as for left, but flipped
            MessagingCenter.Send ("Swiped to the Right", "RightSwipe");

        }
    }
}

      

+4


source







All Articles