source/SkiaSharp.Views.Maui/SkiaSharp.Views.Maui.Core/Platform/Apple/SKTouchHandler.cs (90 lines of code) (raw):
#nullable enable
using System;
using System.Linq;
using Foundation;
using UIKit;
namespace SkiaSharp.Views.Maui.Platform
{
internal class SKTouchHandler : UIGestureRecognizer
{
private Action<SKTouchEventArgs>? onTouchAction;
private Func<double, double, SKPoint>? scalePixels;
public SKTouchHandler(Action<SKTouchEventArgs> onTouchAction, Func<double, double, SKPoint> scalePixels)
{
this.onTouchAction = onTouchAction;
this.scalePixels = scalePixels;
DisablesUserInteraction = false;
}
public bool DisablesUserInteraction { get; set; }
public void SetEnabled(UIView view, bool enableTouchEvents)
{
if (view != null)
{
if (!view.UserInteractionEnabled || DisablesUserInteraction)
{
view.UserInteractionEnabled = enableTouchEvents;
}
if (enableTouchEvents && view.GestureRecognizers?.Contains(this) != true)
{
view.AddGestureRecognizer(this);
}
else if (!enableTouchEvents && view.GestureRecognizers?.Contains(this) == true)
{
view.RemoveGestureRecognizer(this);
}
}
}
public void Detach(UIView view)
{
// clean the view
SetEnabled(view, false);
// remove references
onTouchAction = null;
scalePixels = null;
}
public override void TouchesBegan(NSSet touches, UIEvent evt)
{
base.TouchesBegan(touches, evt);
foreach (UITouch touch in touches.Cast<UITouch>())
{
if (!FireEvent(SKTouchAction.Pressed, touch, true))
{
IgnoreTouch(touch, evt);
}
}
}
public override void TouchesMoved(NSSet touches, UIEvent evt)
{
base.TouchesMoved(touches, evt);
foreach (UITouch touch in touches.Cast<UITouch>())
{
FireEvent(SKTouchAction.Moved, touch, true);
}
}
public override void TouchesEnded(NSSet touches, UIEvent evt)
{
base.TouchesEnded(touches, evt);
foreach (UITouch touch in touches.Cast<UITouch>())
{
FireEvent(SKTouchAction.Released, touch, false);
}
}
public override void TouchesCancelled(NSSet touches, UIEvent evt)
{
base.TouchesCancelled(touches, evt);
foreach (UITouch touch in touches.Cast<UITouch>())
{
FireEvent(SKTouchAction.Cancelled, touch, false);
}
}
private bool FireEvent(SKTouchAction actionType, UITouch touch, bool inContact)
{
if (onTouchAction == null || scalePixels == null)
return false;
var id = ((IntPtr)touch.Handle).ToInt64();
var cgPoint = touch.LocationInView(View);
var point = scalePixels(cgPoint.X, cgPoint.Y);
var args = new SKTouchEventArgs(id, actionType, point, inContact);
onTouchAction(args);
return args.Handled;
}
}
}