点击手势识别器不能与 Xamarin Forms 中的形状一起使用?

Tap Gesture Recognizer not working with Shapes in Xamarin Forms?

我在 Xamarin Forms 中为 Shape 对象配备了点击手势识别器以对点击事件做出反应,但是它不起作用。我尝试过 Path、Polygone 和 Polyline 对象。将形状包裹在一个框架中是有效的——但前提是我点击形状外部的区域。那不是我想要的。包装在 ContentView 中也没有效果。也许这就是形状在 XF 中仍处于实验阶段的原因(您必须在 App class 中设置 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
            };
        }
    }

有谁知道如何使手势与形状一起工作的解决方案或变通方法?

为什么不在 Triangle 周围加上 Frame 并在其中添加 TabGestureRecognizer

这是 Polygon/Polyline 的 iOS 实现中的错误。

解决方法是,将 Shape 包装在另一个视图中,并将 Polygon 上的 InputTransparent 设置为 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 是矩形的,将 TapGestureRecognizer 添加到 Shape 将触发 View 框的 Tap,而不是其中的形状。这是在 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/