Skip to content

Commit b9553ef

Browse files
authored
Merge pull request #15 from RobertStefancic/oxy_zoom_fix_ios
Fix: Zoom is not working on iOS
2 parents 707a12c + ef25e00 commit b9553ef

File tree

1 file changed

+26
-101
lines changed

1 file changed

+26
-101
lines changed

Source/OxyPlot.Maui.Skia/Platforms/iOS/Effects/PlatformTouchEffect.cs

+26-101
Original file line numberDiff line numberDiff line change
@@ -8,24 +8,18 @@ namespace OxyPlot.Maui.Skia.ios.Effects;
88

99
public 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

Comments
 (0)