This repository was archived by the owner on May 1, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1.9k
This repository was archived by the owner on May 1, 2024. It is now read-only.
[Bug] Overwrite method touch on iOS native overlap by Touch Effect #14315
Copy link
Copy link
Open
Labels
a/customrenderera/gestures 🖖s/unverifiedNew report that has yet to be verifiedNew report that has yet to be verifiedt/bug 🐛
Description
Description
I had using Xamarin Form to custom my page with a custom Renderer.
And custom Touch with Touch Effect: https://docs.microsoft.com/en-us/xamarin/xamarin-forms/app-fundamentals/effects/touch-tracking
When I enable my custom Render Native iOS. TouchBegan, Move, End just fire once on Native View. And after the event touch always fire from Touch Effect without fire Event on Native View myCustom. I try to detect something but seem Touch Effect is always top of the Main Page. Hit events method in UIView Custom still received events from my Native Custom UIView.
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:tt="clr-namespace:Test.TouchTracking"
xmlns:skia="clr-namespace:SkiaSharp.Views.Forms;assembly=SkiaSharp.Views.Forms" xmlns:ext="clr-namespace:Test"
x:Class="Test.MainPage">
<Grid x:Name="MainPageGrid">
<Grid.Effects>
<tt:TouchEffect Capture="True" TouchAction="OnTouchEffectAction"/>
</Grid.Effects>
<skia:SKCanvasView x:Name="drawedFingerView" PaintSurface="drawed_PaintSurface" BackgroundColor="Yellow"/>
<ContentView x:Name="contentViewTextParent" x:FieldModifier="public" HorizontalOptions="Center" BackgroundColor="AliceBlue" VerticalOptions="CenterAndExpand">
<ext:TestTouchFingerCanvas x:Name="TestFingerCanvas" HorizontalOptions="Fill" VerticalOptions="Fill"/>
</ContentView>
</Grid>
</ContentPage>
using System;
using CoreGraphics;
using Foundation;
using Test.iOS;
using Test.iOS.Views;
using Test;
using UIKit;
using Xamarin.Forms;
using Xamarin.Forms.Platform.iOS;
using Test.TouchTracking;
[assembly: ExportRenderer(typeof(TestTouchFingerCanvas), typeof(FingerPaintCanvasRenderer))]
namespace Test.iOS.Views
{
public class FingerPaintCanvasRenderer : ViewRenderer<TestTouchFingerCanvas, FingerPaintCanvasView>
{
public FingerPaintCanvasRenderer() : base()
{
}
protected override void OnElementChanged(ElementChangedEventArgs<TestTouchFingerCanvas> e)
{
if (e.NewElement != null)
{
if (Control == null)
{
var view = new FingerPaintCanvasView(UIScreen.MainScreen.Bounds);
SetNativeControl(view);
}
e.NewElement.TouchAction += OnTouchAction;
}
if (e.OldElement != null)
{
e.OldElement.TouchAction -= OnTouchAction;
}
base.OnElementChanged(e);
}
private void OnTouchAction(object sender, TouchActionEventArgs e)
{
if (null != Control)
{
}
}
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
}
}
}
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using CoreGraphics;
using Foundation;
using Test.iOS.Common;
using SkiaSharp;
using Test.iOS.Common;
using Test.TouchTracking;
using UIKit;
namespace Test.iOS
{
public class FingerPaintCanvasView : UIView
{
Dictionary<IntPtr, FingerPaintPolyline> inProgressPolylines = new Dictionary<IntPtr, FingerPaintPolyline>();
List<FingerPaintPolyline> completedPolylines = new List<FingerPaintPolyline>();
Dictionary<IntPtr, CGPoint> inProgressFirstPoints = new Dictionary<IntPtr, CGPoint>();
float haftSize = 0;
bool actionErase = false;
public static int MAX = 100;
public float StrokeWidth;
public static FingerPaintCanvasView Instance;
public FingerPaintCanvasView() : base()
{
Instance = this;
}
public FingerPaintCanvasView(RectangleF frame) : base(frame)
{
Instance = this;
}
public FingerPaintCanvasView(CGRect rect) : base(rect)
{
Instance = this;
}
public object TouchObject { get; set; }
public override void TouchesBegan(NSSet touches, UIEvent evt)
{
base.TouchesBegan(touches, evt);
foreach (UITouch touch in touches.Cast<UITouch>())
{
// Create a FingerPaintPolyline, set the initial point, and store it
FingerPaintPolyline polyline = new FingerPaintPolyline
{
Color = UIColor.Blue.CGColor,
StrokeWidth = StrokeWidth,
};
polyline.Path.MoveToPoint(touch.LocationInView(this));
inProgressPolylines.Add(touch.Handle, polyline);
}
SetNeedsDisplay();
}
public override void TouchesMoved(NSSet touches, UIEvent evt)
{
base.TouchesMoved(touches, evt);
foreach (UITouch touch in touches.Cast<UITouch>())
{
// Add point to path
inProgressPolylines[touch.Handle].Path.AddLineToPoint(touch.LocationInView(this));
}
SetNeedsDisplay();
}
public override void TouchesEnded(NSSet touches, UIEvent evt)
{
base.TouchesEnded(touches, evt);
foreach (UITouch touch in touches.Cast<UITouch>())
{
// Get polyline from dictionary and remove it from dictionary
FingerPaintPolyline polyline = inProgressPolylines[touch.Handle];
inProgressPolylines.Remove(touch.Handle);
// Add final point to path and save with completed polylines
polyline.Path.AddLineToPoint(touch.LocationInView(this));
completedPolylines.Add(polyline);
}
SetNeedsDisplay();
}
public override void TouchesCancelled(NSSet touches, UIEvent evt)
{
base.TouchesCancelled(touches, evt);
foreach (UITouch touch in touches.Cast<UITouch>())
{
inProgressPolylines.Remove(touch.Handle);
}
SetNeedsDisplay();
}
public override void Draw(CGRect rect)
{
base.Draw(rect);
using (CGContext context = UIGraphics.GetCurrentContext())
{
// Stroke settings
context.SetLineCap(CGLineCap.Round);
context.SetLineJoin(CGLineJoin.Round);
// Draw the completed polylines
foreach (FingerPaintPolyline polyline in completedPolylines)
{
context.SetStrokeColor(UIColor.Blue.CGColor);
context.SetLineWidth(3);
context.AddPath(polyline.Path);
context.DrawPath(CGPathDrawingMode.Stroke);
}
// Draw the in-progress polylines
foreach (FingerPaintPolyline polyline in inProgressPolylines.Values)
{
context.SetStrokeColor(UIColor.Red.CGColor);
context.SetLineWidth(3);
context.AddPath(polyline.Path);
context.DrawPath(CGPathDrawingMode.Stroke);
}
}
}
}
}
Steps to Reproduce
- Custom Renderer for UI View on Xamarin Forms. Overwrite method touch relate on native UIVIew iOS
- Enable view content view to contain native uiview. Touch on it
- Event touch on TouchEffect was fire and touch on native was overlap
Expected Behavior
The only touch on native UI view was fire when it enables without Touch Effect fire events.
Actual Behavior
Touch Effect fire events
Basic Information
- Version with issue: XamarinForms 5.3
- Last known good version:
- Platform Target Frameworks:
- iOS: 14
- NuGet Packages: SkiaCsharp, Xamarin Forms
- Affected Devices: Real and Simulator iOS OS 14
Environment
Show/Hide Visual Studio info
Build Logs
Metadata
Metadata
Assignees
Labels
a/customrenderera/gestures 🖖s/unverifiedNew report that has yet to be verifiedNew report that has yet to be verifiedt/bug 🐛