@@ -8,24 +8,18 @@ namespace OxyPlot.Maui.Skia.ios.Effects;
88
99public class PlatformTouchEffect : PlatformEffect
1010{
11- UIView view ;
12- TouchRecognizer touchRecognizer ;
11+ private UIView view ;
12+ private TouchRecognizer touchRecognizer ;
1313
1414 protected override void OnAttached ( )
1515 {
16- // Get the iOS UIView corresponding to the Element that the effect is attached to
1716 view = Control ?? Container ;
1817
19- // Uncomment this line if the UIView does not have touch enabled by default
20- //view.UserInteractionEnabled = true;
21-
22- // Get access to the TouchEffect class in the .NET Standard library
2318 var touchEffect = Element . Effects . OfType < MyTouchEffect > ( ) . FirstOrDefault ( ) ;
2419
2520 if ( touchEffect != null && view != null )
2621 {
27- // Create a TouchRecognizer for this UIView
28- touchRecognizer = new TouchRecognizer ( Element , view , touchEffect ) ;
22+ touchRecognizer = new TouchRecognizer ( Element , touchEffect ) ;
2923 view . AddGestureRecognizer ( touchRecognizer ) ;
3024 }
3125 }
@@ -34,140 +28,71 @@ protected override void OnDetached()
3428 {
3529 if ( touchRecognizer != null )
3630 {
37- // Clean up the TouchRecognizer object
3831 touchRecognizer . Detach ( ) ;
39-
40- // Remove the TouchRecognizer from the UIView
4132 view . RemoveGestureRecognizer ( touchRecognizer ) ;
4233 }
4334 }
4435}
4536
46- class TouchRecognizer : UIGestureRecognizer
37+ internal class TouchRecognizer : UIGestureRecognizer
4738{
48- Microsoft . Maui . Controls . Element element ; // Forms element for firing events
49- UIView view ; // iOS UIView
50- MyTouchEffect touchPlatformEffect ;
51-
52- static Dictionary < UIView , TouchRecognizer > viewDictionary = new ( ) ;
39+ private readonly Microsoft . Maui . Controls . Element element ;
40+ private readonly MyTouchEffect touchEffect ;
41+ private uint activeTouchesCount = 0 ;
5342
54- static Dictionary < long , TouchRecognizer > idToTouchDictionary = new ( ) ;
55-
56- public TouchRecognizer ( Microsoft . Maui . Controls . Element element , UIView view , MyTouchEffect touchPlatformEffect )
43+ public TouchRecognizer ( Microsoft . Maui . Controls . Element element , MyTouchEffect touchEffect )
5744 {
5845 this . element = element ;
59- this . view = view ;
60- this . touchPlatformEffect = touchPlatformEffect ;
46+ this . touchEffect = touchEffect ;
6147
62- viewDictionary . Add ( view , this ) ;
48+ ShouldRecognizeSimultaneously = new UIGesturesProbe ( ( _ , _ ) => true ) ;
6349 }
6450
6551 public void Detach ( )
6652 {
67- viewDictionary . Remove ( view ) ;
53+ ShouldRecognizeSimultaneously = null ;
6854 }
6955
70- // touches = touches of interest; evt = all touches of type UITouch
7156 public override void TouchesBegan ( NSSet touches , UIEvent evt )
7257 {
7358 base . TouchesBegan ( touches , evt ) ;
74-
75- foreach ( UITouch touch in touches . Cast < UITouch > ( ) )
76- {
77- long id = ( ( IntPtr ) touch . Handle ) . ToInt64 ( ) ;
78- FireEvent ( this , id , TouchActionType . Pressed , touch , true ) ;
79-
80- if ( ! idToTouchDictionary . ContainsKey ( id ) )
81- {
82- idToTouchDictionary . Add ( id , this ) ;
83- }
84- }
59+ activeTouchesCount += touches . Count . ToUInt32 ( ) ;
60+ FireEvent ( touches , TouchActionType . Pressed , true ) ;
8561 }
8662
8763 public override void TouchesMoved ( NSSet touches , UIEvent evt )
8864 {
8965 base . TouchesMoved ( touches , evt ) ;
9066
91- foreach ( UITouch touch in touches . Cast < UITouch > ( ) )
67+ if ( activeTouchesCount == touches . Count . ToUInt32 ( ) )
9268 {
93- long id = ( ( IntPtr ) touch . Handle ) . ToInt64 ( ) ;
94- CheckForBoundaryHop ( touch ) ;
95- if ( idToTouchDictionary [ id ] != null )
96- {
97- FireEvent ( idToTouchDictionary [ id ] , id , TouchActionType . Moved , touch , true ) ;
98- }
69+ FireEvent ( touches , TouchActionType . Moved , true ) ;
9970 }
10071 }
10172
10273 public override void TouchesEnded ( NSSet touches , UIEvent evt )
10374 {
10475 base . TouchesEnded ( touches , evt ) ;
105-
106- foreach ( UITouch touch in touches . Cast < UITouch > ( ) )
107- {
108- long id = ( ( IntPtr ) touch . Handle ) . ToInt64 ( ) ;
109- CheckForBoundaryHop ( touch ) ;
110- if ( idToTouchDictionary [ id ] != null )
111- {
112- FireEvent ( idToTouchDictionary [ id ] , id , TouchActionType . Released , touch , false ) ;
113- }
114-
115- idToTouchDictionary . Remove ( id ) ;
116- }
76+ activeTouchesCount -= touches . Count . ToUInt32 ( ) ;
77+ FireEvent ( touches , TouchActionType . Released , false ) ;
11778 }
11879
11980 public override void TouchesCancelled ( NSSet touches , UIEvent evt )
12081 {
12182 base . TouchesCancelled ( touches , evt ) ;
122-
123- foreach ( UITouch touch in touches . Cast < UITouch > ( ) )
124- {
125- long id = ( ( IntPtr ) touch . Handle ) . ToInt64 ( ) ;
126- idToTouchDictionary . Remove ( id ) ;
127- }
12883 }
12984
130- void CheckForBoundaryHop ( UITouch touch )
85+ private void FireEvent ( NSSet touches , TouchActionType actionType , bool isInContact )
13186 {
132- long id = ( ( IntPtr ) touch . Handle ) . ToInt64 ( ) ;
133-
134- // TODO: Might require converting to a List for multiple hits
135- TouchRecognizer recognizerHit = null ;
87+ UITouch [ ] uiTouches = touches . Cast < UITouch > ( ) . ToArray ( ) ;
88+ long id = ( ( IntPtr ) uiTouches . First ( ) . Handle ) . ToInt64 ( ) ;
89+ Point [ ] points = new Point [ uiTouches . Length ] ;
13690
137- foreach ( UIView view in viewDictionary . Keys )
138- {
139- CGPoint location = touch . LocationInView ( view ) ;
140-
141- if ( new CGRect ( new CGPoint ( ) , view . Frame . Size ) . Contains ( location ) )
142- {
143- recognizerHit = viewDictionary [ view ] ;
144- }
145- }
146- if ( recognizerHit != idToTouchDictionary [ id ] )
91+ for ( int i = 0 ; i < uiTouches . Length ; i ++ )
14792 {
148- if ( idToTouchDictionary [ id ] != null )
149- {
150- FireEvent ( idToTouchDictionary [ id ] , id , TouchActionType . Pressed , touch , true ) ;
151- }
152- if ( recognizerHit != null )
153- {
154- FireEvent ( recognizerHit , id , TouchActionType . Released , touch , true ) ;
155- }
156- idToTouchDictionary [ id ] = recognizerHit ;
93+ CGPoint cgPoint = uiTouches [ i ] . LocationInView ( View ) ;
94+ points [ i ] = new ( cgPoint . X , cgPoint . Y ) ;
15795 }
96+ touchEffect . OnTouchAction ( element , new ( id , actionType , points , isInContact ) ) ;
15897 }
159-
160- void FireEvent ( TouchRecognizer recognizer , long id , TouchActionType actionType , UITouch touch , bool isInContact )
161- {
162- // Convert touch location to Maui Point value
163- CGPoint cgPoint = touch . LocationInView ( recognizer . View ) ;
164- Point xfPoint = new Point ( cgPoint . X , cgPoint . Y ) ;
165-
166- // Get the method to call for firing events
167- var onTouchAction = recognizer . touchPlatformEffect . OnTouchAction ;
168-
169- // Call that method
170- onTouchAction ( recognizer . element ,
171- new TouchActionEventArgs ( id , actionType , new [ ] { xfPoint } , isInContact ) ) ;
172- }
173- }
98+ }
0 commit comments