virtual public Gesture UpdateGestureFromTouches(NSSet touches, TouchEventType touchType) { if (touches.Count() == 0) { // No touches, do nothing return(null); } // Update the set of current touches switch (touchType) { case TouchEventType.TouchBegan: case TouchEventType.TouchMoved: var touchesUnion = currentTouches.Union(touches); var touchesArray = new UITouch[touchesUnion.Count()]; int i = 0; foreach (UITouch touch in touchesUnion) { touchesArray[i] = touch; i++; } currentTouches = new NSSet(touchesArray); break; case TouchEventType.TouchCanceled: case TouchEventType.TouchEnded: var notInTouches = NSPredicate.FromExpression(new NSPredicateEvaluator((evaluatedObject, bindings) => !touches.Contains(evaluatedObject))); currentTouches = currentTouches.FilterUsingPredicate(notInTouches); break; } var expectedTouchCount = (this is SingleFingerGesture) ? 1 : 2; if (currentTouches.Count() == expectedTouchCount) { this.UpdateGesture(null); return(this); } else { this.FinishGesture(); this.refreshTimer?.Dispose(); // Erase reference to timer in case callback fires one last time this.refreshTimer = null; // Switch to two-finger gesture if was single-finger. If was two-finger, return null return((this is SingleFingerGesture) ? Gesture.StartGestureFromTouches(currentTouches, this.SceneView, LastUsedObject, manager) : null); } }