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?
source to share
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");
}
}
}
source to share