Gesture Recognisers are a great feature added in iOS 3.2 (ages ago!), and using them in MonoTouch couldn’t be simpler. I’ll skip over a discussion on how they work, if you want more info on the recognisers themselves, be sure to check out the Apple documentation.
Selectors
UIGestureRecognizer instances use selectors to call back methods in your class. Selectors are supported in MonoTouch, you just need to do a little more work:
[Export("ViewTapSelector")] protected void OnViewTapped(UIGestureRecognizer sender) { MessageLabel.Text = "View Tapped"; }
Essentially you need to create a method, then mark it for export. This tells the MonoTouch compiler to make the method callable by ObjC code. Make sure the containing class is decorated with the Register attribute (ViewControllers are automatically registered).
First Recogniser
Setting up a UIGestureRecognizer is very easy:
var tapRecogniser = new UITapGestureRecognizer(this, new MonoTouch.ObjCRuntime.Selector("ViewTapSelector")); View.AddGestureRecognizer(tapRecogniser);
This creates a new recogniser, with a callback and assigns it to the root view for the controller. You don’t need to worry about garbage collection since the view will retain the recogniser. You can access all of the recognisers for a view by using the GestureRecognizers property.
That’s it!
Surprisingly that’s all there is to it! You can download an example project here, or just view the code snippet below to flesh out the principles:
Sample Code
private void SetupGestureRecognisers() { var tapRecogniser = new UITapGestureRecognizer(this, new MonoTouch.ObjCRuntime.Selector("ViewTapSelector")); View.AddGestureRecognizer(tapRecogniser); var doubleTapRecogniser = new UITapGestureRecognizer(this, new MonoTouch.ObjCRuntime.Selector("ViewDoubleTapSelector")); doubleTapRecogniser.NumberOfTapsRequired = 3; View.AddGestureRecognizer(doubleTapRecogniser); var longPressRecogniser = new UILongPressGestureRecognizer(this, new MonoTouch.ObjCRuntime.Selector("LongPressSelector")); View.AddGestureRecognizer(longPressRecogniser); var panRecogniser = new UIPanGestureRecognizer(this, new MonoTouch.ObjCRuntime.Selector("LabelPanSelector")); DragLabel.AddGestureRecognizer(panRecogniser); } [Export("ViewTapSelector")] protected void OnViewTapped(UIGestureRecognizer sender) { MessageLabel.Text = "View Tapped"; } [Export("ViewDoubleTapSelector")] protected void OnViewDoubleTapped(UIGestureRecognizer sender) { MessageLabel.Text = "View Triple Tapped"; } [Export("LongPressSelector")] protected void OnLongPress(UIGestureRecognizer sender) { MessageLabel.Text = "View Long Pressed"; } [Export("LabelPanSelector")] protected void OnLabelPan(UIGestureRecognizer sender) { var panRecogniser = sender as UIPanGestureRecognizer; if (panRecogniser == null) return; switch (panRecogniser.State) { case UIGestureRecognizerState.Began: _originalPosition = DragLabel.Frame.Location; break; case UIGestureRecognizerState.Cancelled: case UIGestureRecognizerState.Failed: DragLabel.Frame = new RectangleF(_originalPosition, DragLabel.Frame.Size); break; case UIGestureRecognizerState.Changed: var movement = panRecogniser.TranslationInView(View); var newPosition = new PointF(movement.X + _originalPosition.X, movement.Y + _originalPosition.Y); DragLabel.Frame = new RectangleF(newPosition, DragLabel.Frame.Size); break; } }