From a1da3212f0aeb4c1f99024e48b2e3f2876646634 Mon Sep 17 00:00:00 2001 From: Filip Navara Date: Sun, 7 Jul 2024 09:41:41 +0200 Subject: [PATCH] Correctly implement the UIGestureRecognizer state machine --- .../Touch/TouchBehavior.macios.cs | 21 ++++++++++--------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/src/CommunityToolkit.Maui/Behaviors/PlatformBehaviors/Touch/TouchBehavior.macios.cs b/src/CommunityToolkit.Maui/Behaviors/PlatformBehaviors/Touch/TouchBehavior.macios.cs index 8c151a641b..f2d939e87e 100644 --- a/src/CommunityToolkit.Maui/Behaviors/PlatformBehaviors/Touch/TouchBehavior.macios.cs +++ b/src/CommunityToolkit.Maui/Behaviors/PlatformBehaviors/Touch/TouchBehavior.macios.cs @@ -222,6 +222,16 @@ void HandleTouch(TouchStatus status, TouchInteractionStatus? interactionStatus = return; } + // We MUST implement the Apple state machine. This ensures that the interaction + // between multiple simultaneous touch recognizers works correctly. + // https://developer.apple.com/documentation/uikit/touches_presses_and_gestures/implementing_a_custom_gesture_recognizer/about_the_gesture_recognizer_state_machine?language=objc + State = status switch + { + TouchStatus.Canceled => UIGestureRecognizerState.Failed, + TouchStatus.Completed => UIGestureRecognizerState.Recognized, + _ => UIGestureRecognizerState.Possible, + }; + if (interactionStatus is TouchInteractionStatus.Started) { behavior.HandleUserInteraction(TouchInteractionStatus.Started); @@ -260,19 +270,10 @@ public override bool ShouldRecognizeSimultaneously(UIGestureRecognizer gestureRe { touchGesture.HandleTouch(TouchStatus.Canceled, TouchInteractionStatus.Completed); touchGesture.isCanceled = true; - } - - return true; - } - - public override bool ShouldReceiveTouch(UIGestureRecognizer recognizer, UITouch touch) - { - if (recognizer.View.IsDescendantOfView(touch.View)) - { return true; } - return touch.View.IsDescendantOfView(recognizer.View) && (touch.View.GestureRecognizers is null || touch.View.GestureRecognizers.Length == 0); + return false; } } }