Tap Gesture Recognizer无法与Xamarin Forms中的Shapes一起使用吗?

问题描述

我已经为Xamarin Forms的Shape对象配备了Tap Gesture Recognizer,可以对Tap事件做出反应,但是它不起作用。我尝试使用Path,polygone和polyline对象。将形状包装在框架中是可行的-但只有当我点击形状以外的区域时,才可以。那不是我想要的在ContentView中包装也没有效果。也许是因为形状仍在XF中处于实验阶段(您必须在App类中设置Shapes_Experimental标志才能使用形状)?

以下是在iOS上测试过的适用于盒子但不适用于三角形的简单示例:

public class TestPage : ContentPage
    {
        public TestPage()
        {
            var tgr = new TapGestureRecognizer();
            tgr.Tapped += async (s,e) => {
                await displayAlert("Info","Tapped","OK");
            };

            polygon triangle = new polygon
            {
                Points = new PointCollection(),Fill = Brush.Blue,};
            triangle.Points.Add(new Point(0,0));
            triangle.Points.Add(new Point(100,0));
            triangle.Points.Add(new Point(50,50));

            triangle.GestureRecognizers.Add(tgr);

            BoxView Box = new BoxView
            {
                HeightRequest = 50,Color = Color.Red
            };

            Box.GestureRecognizers.Add(tgr);

            Content = new StackLayout
            {
                Children = { triangle,Box },HorizontalOptions = Layoutoptions.Center,VerticalOptions = Layoutoptions.Center
            };
        }
    }

有人知道如何使手势与形状配合使用的解决方案或解决方法吗?

谢谢您的帮助!

解决方法

这是iOS上的多边形/折线实现的错误。

要解决此问题,请将Shape包裹在另一个视图中,并将InputTransparent上的Polygon设置为true。 当Shape在另一个元素中时,Shape仍在顶部,并且仍然从用户那里获得水龙头,因此您必须将水龙头向下传递给包装容器(无论是Frame还是ContentView)。例如:

    var tgr = new TapGestureRecognizer();
    tgr.Tapped += async (s,e) => {
        await DisplayAlert("Info","Tapped","OK");
    };

    Polygon triangle = new Polygon
    {
        Points = new PointCollection(),Fill = Brush.Blue,};
    triangle.Points.Add(new Point(0,0));
    triangle.Points.Add(new Point(100,0));
    triangle.Points.Add(new Point(50,50));
    triangle.InputTransparent = true;  // <------------------------set InputTransparent to True

    var frame= new Frame(); 
    frame.Content = triangle; // <--------------------- add to Frame
 
    frame.GestureRecognizers.Add(tgr); // <-----------TapGestureRecognizer on Frame

    Content = new StackLayout
    {
        Children = { frame },// <------------------------ add Frame to view heirarchy
        HorizontalOptions = LayoutOptions.Center,VerticalOptions = LayoutOptions.Center
    };

更新: 如果只需要在敲击实际三角形时才进行敲击工作,则需要在特定于平台的渲染器中进行敲击,并使用iOS / Android / UWP SDK API进行命中测试。

由于Xamarin.Forms Shape是一个View,而View是一个矩形,因此在Shape中添加TapGestureRecognizer会触发Tap for the View框,而不是其中的形状。当Shape未包装在Frame等中时,这就是在Android上发生的事情。

在Xamarin论坛上讨论了如何在Xamarin.Forms中获取抽头坐标:https://forums.xamarin.com/discussion/17767/touch-coordinates-in-tapgesturerecognizer

有关在Xamarin.iOS中处理触摸事件的文档:https://docs.microsoft.com/en-us/xamarin/ios/app-fundamentals/touch/ 有关在Xamarin.Android中处理触摸事件的文档:https://docs.microsoft.com/en-us/xamarin/android/app-fundamentals/touch/touch-in-android 有关在UWP中处理触摸事件的文档:https://docs.microsoft.com/en-us/windows/uwp/design/input/touch-interactions

您也可以对形状使用SkiaSharp:https://docs.microsoft.com/en-us/xamarin/xamarin-forms/user-interface/graphics/skiasharp/transforms/touch

还有一个付费插件,在上面链接的Xamarin论坛讨论中提到(我不能保证),声称可以确定触摸发生的位置:https://www.mrgestures.com/

,

为什么不将Frame包裹在Triangle周围并在其中添加TabGestureRecognizer