In Xamarin.Forms I want to be able to swipe left and right to navigate a list of pictures. At the moment I just want to be able to fire an event each 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 Renderer:
[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 display the swipe right event is activated, but nothing happens when I try to swipe on top of the image. I am guessing my logic on the renderer is wrong?
After much pain and searching around the web I found the solution.
What you need to do is simple: in the renderer declare and add the gesture. Make sure you create a swipe gesture for right and left each by declaring their direction. from there use a lambda to call the function you want activated for the specific swipe:
Placeholder class for the Swipe Gestures.
public class LRMasterDetailPage : ContentView
{
}
Image Page that holds one image at the 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");
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With