我正在尝试使用覆盖视图实现MKMapView,该视图绘制可编辑的多边形。因此,我需要有选择地捕获针对顶点的触摸手势,但允许其他触摸/手势通过,以便允许滚动和缩放地图。
那么,如何根据其坐标以编程方式将选定的触摸发送到地图或叠加层?
以下代码将其简化为一个简化方案:叠加视图的左侧为红色,右侧为蓝色。一侧应捕获触摸事件,而另一侧应允许地图交互。
地图和叠加层都是上的子视图SuperView
:
public sealed class SuperView: UIView
{
readonly UIView map = new MapView();
readonly UIView overlay = new Overlay();
public SuperView()
{
AddSubview(map);
AddSubview(overlay);
}
public override UIView HitTest(CGPoint point, UIEvent uievent)
{
return point.X < Frame.Width / 2 ? map : overlay;
}
}
该MapView
派生自MKMapView
,只有确保允许滚动:
public sealed class MapView: MKMapView
{
public MapView() : base(UIScreen.MainScreen.Bounds)
{
ScrollEnabled = true;
}
}
该Overlay
包含一个手势识别和可视化的两个区域:
public sealed class Overlay: UIView
{
public Overlay() : base(UIScreen.MainScreen.Bounds)
{
BackgroundColor = new UIColor(0, 0, 0, 0);
AddGestureRecognizer(new Recognizer());
}
public override void Draw(CGRect rect)
{
using (var context = UIGraphics.GetCurrentContext()) {
context.SetFillColor(new CGColor(1, 0, 0, 0.25f));
context.FillRect(new CGRect(rect.Left, rect.Top, rect.Width / 2, rect.Height));
context.SetFillColor(new CGColor(0, 0, 1, 0.25f));
context.FillRect(new CGRect(rect.Width / 2, rect.Top, rect.Width / 2, rect.Height));
}
}
}
识别器很简单:
public sealed class Recognizer: UIGestureRecognizer
{
public override void TouchesBegan(NSSet touches, UIEvent evt)
{
Console.WriteLine("TouchesBegan");
base.TouchesBegan(touches, evt);
}
public override void TouchesMoved(NSSet touches, UIEvent evt)
{
Console.WriteLine("TouchesMoved");
base.TouchesMoved(touches, evt);
}
public override void TouchesEnded(NSSet touches, UIEvent evt)
{
Console.WriteLine("TouchesEnded");
base.TouchesEnded(touches, evt);
}
public override void TouchesCancelled(NSSet touches, UIEvent evt)
{
Console.WriteLine("TouchesCancelled");
base.TouchesCancelled(touches, evt);
}
}
出现的屏幕如下所示:
触摸红色部分时,我希望与地图互动-这是行不通的。触摸蓝色部分时,我想查看手势识别器的控制台输出-确实可以工作。
什么不起作用:
将覆盖图调整为仅屏幕的一半。
在此人工示例中,这将有所帮助。但是在我的现实应用中,触摸与不触摸之间的区别更加复杂。
将手势检测器添加到MapView
。
由于每个手势识别器将以不确定的顺序接收触摸事件,因此您永远不会知道地图或手势检测器是否首先接收到触摸事件。因此,即使触摸不应该收到地图,地图也可能已经在滚动。
覆盖HitTest
或PointInside
。
我试图重写这些方法SuperView
,MapView
和/或Overlay
。但是它们要么没有被调用,要么似乎没有效果。至少我可以防止手势识别器收到红色区域的触摸。但是它没有达到预期的地图。也许我做错了。但似乎地图忽略了转发的触摸。
我似乎已经解决了上述问题。显然,MKMapView
不应该是一个子视图,但需要的是View
的ViewController
:
public sealed class SuperView: UIViewController
{
readonly UIView map = new MKMapView();
readonly UIView overlay = new Overlay();
public SuperView()
{
View = map;
map.AddSubview(overlay);
}
}
然后,Overlay
视图获取HitTest
实现:
public override UIView HitTest(CGPoint point, UIEvent uievent)
{
return point.X < Frame.Width / 2 ? null : base.HitTest(point, uievent);
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句