如何使MKAnnotationView触摸敏感?

我目前有一个地图视图上有一些注释。 我有自定义图像的注释。 我试图解决的问题是图像的敏感性。 当我试图拖动它们时,感觉就像我必须触摸确切的中心来重点关注它。 有没有办法让触摸范围更大?

为此,您需要MKAnnotationView以创build您自己的自定义MKAnnotationView 。 在你的子类中,覆盖下列函数:

 - (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent*)event { // Return YES if the point is inside an area you want to be touchable } - (UIView*)hitTest:(CGPoint)point withEvent:(UIEvent*)event { // Return the deepest view that the point is inside of. } 

这允许按下交互式视图(例如button等)。 MKAnnotationView的默认实现在MKAnnotationViewhitTest上并不严格,因为它允许实际上在一个注释中的button被发送到不同的注释。 它通过找出离接触点最近的注释中心并将事件发送到该注释来做到这一点,这样使得紧密的(重叠的)注释不会阻止彼此被select。 然而,在你的情况下,如果用户要select并拖动最上面的注释,你可能想阻止其他注释,所以上面的方法可能是你想要的,否则它会设置你在正确的path。

编辑:我在评论中被问到hitTest:withEvent:一个示例实现hitTest:withEvent: – 这取决于你正在试图达到什么。 原始问题build议在注释中触摸和拖动图像,而在我的情况下,我在注释中有一些button,我想要交互。 这是我的代码:

 - (UIView*)hitTest:(CGPoint)point withEvent:(UIEvent*)event { UIView* hitView = [super hitTest:point withEvent:event]; if (hitView != nil) { // ensure that the callout appears above all other views [self.superview bringSubviewToFront:self]; // we tapped inside the callout if (CGRectContainsPoint(self.resultView.callButton.frame, point)) { hitView = self.resultView.callButton; } else if (CGRectContainsPoint(self.resultView.addButton.frame, point)) { hitView = self.resultView.addButton; } else { hitView = self.resultView.viewDetailsButton; } [self preventSelectionChange]; } return hitView; } 

正如你所看到的那样非常简单 – MKAnnotationView实现(在我的实现的第一行被称为super )只返回第一个(最外层)视图,而不是通过视图层次深入查看触摸的哪个子视图其实在里面。 在我的情况下,我只是检查触摸是否在三个button之一,并返回这些。 在其他情况下,您可以通过层次结构或更复杂的命中testing进行简单的基于矩形的钻取,例如,以避免视图中的透明区域允许触摸穿过这些部分。 如果您需要向下钻取, CGRectContainsPoint可以按照我使用过的方法使用CGRectContainsPoint ,但请记住将您的点偏移到您钻入的每个视图级别的本地视图坐标中。

preventSelectionChange方法是为了防止我的自定义注释被选中,我将它作为一个可自定义的/交互式的地图引脚标注,并保持它所涉及的引脚select,而不是允许select更改为这个注释。

你有没有inheritanceMKAnnotationView,或者你只是改变它的图像属性?

这里是设置图片属性的文档。

讨论:为这个属性分配一个新的图像也改变了视图框架的大小,使它匹配新图像的宽度和高度。 视图框架的位置不会改变。

检查您的注释视图的框架的大小,这是您的对象可以接受触摸的地方。

我以下面的方式实现了类似的东西

  1. 创build处理触摸的手势识别器类的子类
  2. 创buildUIImage类的子类,这个类使用识别器类来处理你的手势
  3. 在注释中使用这个

手势识别器子类将处理您的手势,如果您在图像中的任何一点执行它们。 这应该对你有所帮助

让我们更新这个解决scheme是否适合您…

@jhabbott解决scheme从来没有为我工作,正如我在这里提到的。

我有一个图像和一个标签并排。 通过设置annotationview image属性显示image ,并通过添加UILabel显示标签

我redirect的func point(inside:with:)方法的UILabel之一(其中包括图像区)和hitTest没有返回完全相同的观点,无论我点击标签或图像。 但标签点击没有产生任何callback…

最后,我放大MKAnnotationView框架来封闭标签+图像,我把annotationView.image设置nil ,我创build了我的自定义UIImageView

因为我想要在图像中间的锚点,我必须设置一个自定义的:

 self.frame = CGRect(x: 0, y: 0, width: self.myLabel.frame.width, height: self.myLabel.frame.height) self.centerOffset = CGPoint(x: self.frame.width/2, y: self.myImageView.frame.height/2) 

然后我删除point(inside:with:)hitTest(point:with:)覆盖,什么也没做。

而现在,我的注释观点第一次是完全被动的。