SkiaSharp
SkiaSharp copied to clipboard
In the OnTouch an event is missing when the FlyOut is opened
Description
When a FlyOut is opened on iOS there is no event to indicate a loss of touch. On Android an SKTouchAction.Cancelled is called, but on iOS no event at all.
Why is this a problem? The OnTouch event only gives information about single finger presses. We need to track those to know how many fingers are pressed. If an event is missing there is no way to correct for that. We have to assume it is still touching.
Expected Behavior
The same behavior as on Android, a SKTouchAction.Cancelled ActionType OnTouch event
Actual Behavior
No event
Basic Information
- Version with issue: 2.88.3
- Last known good version: Not known
- Platform Target Frameworks:
- iOS: maui-ios 7.0.86/7.0.100
- Target Devices: Tested on Device - iPhone Pro Max 14 (physical device) and some others
I attempted to recreate a minimal reproducible sample but seeing that only the SKTouchAction.Pressed event is firing on iOS. On Windows, I am seeing other ActionTypes, not just Pressed.
Repo - https://github.com/nm4568/SkiaSharpSamples
XAML
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:skia="clr-namespace:SkiaSharp.Views.Maui.Controls;assembly=SkiaSharp.Views.Maui.Controls"
x:Class="SkiaSharpSample.MainPage">
<StackLayout>
<skia:SKCanvasView x:Name="skCanvasView" PaintSurface="View_PaintSurface" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand"/>
<Label x:Name="DebugLabel"
FontSize="20"
HorizontalOptions="Center"
VerticalOptions="End" />
</StackLayout>
</ContentPage>
C#
using SkiaSharp;
using SkiaSharp.Views.Maui;
using SKCanvasView = SkiaSharp.Views.Maui.Controls.SKCanvasView;
namespace SkiaSharpSample
{
public partial class MainPage : ContentPage
{
SKBitmap skBitmap;
public MainPage()
{
InitializeComponent();
skCanvasView.EnableTouchEvents = true;
skCanvasView.PaintSurface += View_PaintSurface;
skCanvasView.Touch += SkCanvasView_Touch;
}
protected override void OnAppearing()
{
base.OnAppearing();
// Load and render a PNG image using SkiaSharp
RenderSkiaSharpImage();
}
private void RenderSkiaSharpImage()
{
// Get the stream of the embedded resource
var stream = typeof(MainPage).Assembly.GetManifestResourceStream("SkiaSharpSample.Resources.Images.dotnet_bot.png");
// Create a SKBitmap from the stream
skBitmap = SKBitmap.Decode(stream);
}
private void SkCanvasView_Touch(object? sender, SkiaSharp.Views.Maui.SKTouchEventArgs e)
{
switch (e.ActionType)
{
case SKTouchAction.Entered:
DebugLabel.Text = "Entered";
break;
case SKTouchAction.Pressed:
DebugLabel.Text = "Pressed";
break;
case SKTouchAction.Moved:
DebugLabel.Text = "Moved";
break;
case SKTouchAction.Released:
DebugLabel.Text = "Released";
break;
case SKTouchAction.Cancelled:
DebugLabel.Text = "Canceled";
break;
case SKTouchAction.Exited:
DebugLabel.Text = "Exited";
break;
}
// Invalidate the canvas to trigger a redraw
((SKCanvasView)sender).InvalidateSurface();
}
private void View_PaintSurface(object? sender, SkiaSharp.Views.Maui.SKPaintSurfaceEventArgs e)
{
// Get the SKCanvas from the event arguments
var canvas = e.Surface.Canvas;
// Clear the canvas
canvas.Clear(SKColors.White);
// Draw the SKBitmap onto the canvas
canvas.DrawBitmap(skBitmap, new SKPoint(0, 0));
}
}
}
@mattleibow Could you take a look at this? A minimal reproducible sample was added @nm4568 so it should be easy to reproduce. In Mapsui we need to keep track of the number of fingers touching the map. In some scenarios there is no way for use to find out that a finger is not touching anymore.