Skip to content

Instantly share code, notes, and snippets.

@ChuckSavage
Created June 6, 2012 19:58
Show Gist options
  • Save ChuckSavage/2884348 to your computer and use it in GitHub Desktop.
Save ChuckSavage/2884348 to your computer and use it in GitHub Desktop.
MonoTouch Swipe Event
using System.Collections.Generic;
using MonoTouch.Foundation;
using MonoTouch.ObjCRuntime;
using MonoTouch.UIKit;
namespace iOSLib
{
public static class ViewExtensions
{
static Dictionary<UIView, Dictionary<UISwipeGestureRecognizerDirection, SwipeClass>>
views = new Dictionary<UIView, Dictionary<UISwipeGestureRecognizerDirection, SwipeClass>>();
public class SwipeClass : NSObject
{
public class RecognizerDelegate : UIGestureRecognizerDelegate
{
public override bool ShouldReceiveTouch(UIGestureRecognizer recognizer, UITouch touch)
{
return true;
}
}
public readonly UIView View;
Selector selector = new Selector("Swipe");
public delegate void D(SwipeClass sender, UISwipeGestureRecognizer recognizer);
public event D Event = delegate { };
internal SwipeClass(UIView view)
{
View = view;
}
internal void InitSwipe(UISwipeGestureRecognizerDirection direction)
{
if (!View.RespondsToSelector(selector))
{
var swipe = new UISwipeGestureRecognizer();
swipe.AddTarget(this, selector);
swipe.Direction = direction;
swipe.Delegate = new RecognizerDelegate();
View.AddGestureRecognizer(swipe);
}
}
[Export("Swipe")]
void SwipeAction(UISwipeGestureRecognizer recognizer)
{
var e = Event;
e(this, recognizer);
}
}
/// <summary>
/// Add a swipe event to a View easily,
/// and pass the direction and then tack on .Event += ...
/// </summary>
/// <param name="view"></param>
/// <param name="direction"></param>
/// <returns></returns>
public static SwipeClass Swipe(this UIView view, UISwipeGestureRecognizerDirection direction)
{
Dictionary<UISwipeGestureRecognizerDirection, SwipeClass> inner;
SwipeClass swipe;
if (!views.ContainsKey(view))
{
views.Add(view, inner = new Dictionary<UISwipeGestureRecognizerDirection, SwipeClass>());
// need a way to know when view is disposed, so can remove from views so GC
// can collect it.
}
else
inner = views[view];
if (!inner.ContainsKey(direction))
inner.Add(direction, swipe = new SwipeClass(view));
else
swipe = inner[direction];
swipe.InitSwipe(direction);
return swipe;
}
}
}
@ChuckSavage
Copy link
Author

You use it like:

View.Swipe(UISwipeGestureRecognizerDirection.Right).Event += (s, r) =>
    new UIAlertView("Swipe Test", "Swipe " + r.Direction.ToString(), null, "Ok").Show();

@henrikweimenhog
Copy link

Excellent! This just works so well!

@mynameismiek
Copy link

I added a way to remove the views when they are disposed and also extensions for taps. https://gist.github.com/mynameismiek/4996429

@mgamache
Copy link

mgamache commented Jun 2, 2013

When I include this in my project it fails on devices with 'failed (error code=12)'
*** error: can't allocate region
*** set a breakpoint in malloc_error_break to debug
I think it's related to this method:

internal void InitSwipe(UISwipeGestureRecognizerDirection direction)
{
if (!View.RespondsToSelector(selector))
{
var swipe = new UISwipeGestureRecognizer();
swipe.AddTarget(this, selector);
swipe.Direction = direction;
swipe.Delegate = new RecognizerDelegate();
View.AddGestureRecognizer(swipe);
}
}

EDIT*****

I was using MT Beta 3.0.10 after switching back to Stable 2.x it seems to work. I'll leave the error incase someone else has the same issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment