如何使MKAnnotationView触摸敏感? [英] How do I make a MKAnnotationView touch sensitive?

查看:133
本文介绍了如何使MKAnnotationView触摸敏感?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前有一个地图视图,有一些注释。我有自定义图像的注释。我想解决的问题是图像的灵敏度。当我试图拖动它,它感觉像我必须触摸确切的中心,它的重点。是否有办法使触摸范围更大?

I currently have a map view with some annotation on it. I have the annotation with custom images. The problem I am trying to fix is the sensitivity of the images. When I try to drag them, it feels like I have to touch the exact center for it to be focused on. Is there a way to make the touch bounds bigger?

推荐答案

要做到这一点,需要子类 MKAnnotationView 创建自己的自定义 MKAnnotationView 。在你的子类中,重写以下函数:

To do this, you need to subclass MKAnnotationView to create your own custom MKAnnotationView. In your subclass, override the following functions:

- (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.
}

这允许按下交互视图(如按钮等)。 MKAnnotationView 中的默认实现在 pointInside hitTest 因为它允许实际上在一个注释内的按压被发送到不同的注释。它通过找出最接近触摸点的注释中心并将事件发送到该注释来实现,这是因为接近(重叠)注释不会阻止彼此被选择。但是,在您的情况下,如果用户要选择并拖动最上面的注释,您可能想要阻止其他注释,因此上述方法可能是您想要的,否则它会将您设置在正确的路径。

This allows interactive views (such as buttons, etc.) to be pressed. The default implementation in MKAnnotationView is not strict on pointInside and hitTest because it allows presses that are actually inside one annotation to get sent to a different annotation. It does this by figuring out the closest annotation center to the touch-point and sending the events to that annotation, this is so that close-together (overlapping) annotations don't block each other from being selected. However, in your case you probably want to block other annotations if the user is to select and drag the topmost annotation, so the above method is probably what you want, or else it will set you on the right path.

EDIT:
我在评论中询问了 hitTest:withEvent: - 这取决于你正在尝试实现的。原来的问题建议触摸和拖动注释内的图像,而在我的情况下,我有一些按钮在注释,我想要交互。这里是我的代码:

I was asked in comments for an example implementation of hitTest:withEvent: - This depends on exactly what you are trying to achieve. The original question suggested touching and dragging images within the annotation whereas in my case I have some buttons inside the annotation that I want to be interactive. Here's my code:

- (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 )只返回第一个(最外层)视图,层级以查看触摸实际上在哪个子视图。在我的情况下,我只是检查触摸是否在三个按钮之一,并返回那些。在其他情况下,您可以通过层次结构或更复杂的命中测试进行简单的基于矩形的钻取,例如,避免视图中的透明区域允许触摸通过这些部分。如果你确实需要向下钻取, CGRectContainsPoint 可以使用与我使用它相同的方式,但记住要将点偏移到本地视图坐标为每个视图级别你钻

As you can see it's quite simple - The MKAnnotationView implementation (called as super on the first line of my implementation) only returns the first (outermost) view, it does not drill down through the view hierarchy to see which sub-view the touch is actually inside. In my case I just check if the touch is inside one of three buttons and return those. In other circumstances you may have simple rectangle-based drilling down through the hierarchy or more complex hit tests for example to avoid transparent areas within your view to allow touches to pass through those parts. If you do need to drill down, CGRectContainsPoint can be used the same way I have used it, but remember to offset your points into local view coordinates for each view-level you drill into.

preventSelectionChange 方法是防止我的自定义注释被选中,我使用它作为一个可自定义/交互式标注从地图引脚,这保持其相关的引脚选择,而不是允许选择更改为此注释。

The preventSelectionChange method is to prevent my custom annotation from becoming selected, I am using it as a customisable/interactive callout from map pins and this keeps the pin it relates to selected instead of allowing the selection to change to this annotation.

这篇关于如何使MKAnnotationView触摸敏感?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆