点击手势识别器不能与 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/
我在 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/