ios - MKMapView MKPointAnnotation 点击​​事件

我有一个注释列表 (MKPointAnnotation)。我有一个用于整个 View 的 UIViewController,MKMapView 实现 Controller ,我认为这对于检测用户与 map 的交互很有用,我自己的 MKPointAnnotation 实现(子类) Controller ,它告诉如何显示注释。

但是,我对用户检测到点击事件感到震惊。

谷歌搜索告诉我,我必须通过实现以下功能来做一些事情。

- (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control

而且我必须在一些实现 MapViewDelegate(协议(protocol))的类中实现这一点。

但我很困惑,无法前进。谁能告诉我在哪里做什么?

对不起!

最佳答案

有两种方法可以检测用户与您的注释 View 的交互。常见的技术是为您的 MKAnnotationView 定义一个标注(当您点击典型 map 应用程序中的图钉时看到的标准小弹出气泡)。然后您在标准 viewForAnnotation 方法中为您的注释创建注释 View :

- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation
{
    if ([annotation isKindOfClass:[MKUserLocation class]])
        return nil;

    MKAnnotationView *annotationView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:@"loc"];
    annotationView.canShowCallout = YES;
    annotationView.rightCalloutAccessoryView = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];

    return annotationView;
}

通过这样做,您会得到一个标注,但您正在添加一个正确的附件,在我上面的示例中,它是一个披露指示器。这样,他们点击您的注释 View (在我上面的示例中, map 上的一个图钉),他们会看到标注,并且当他们点击该标注的正确附件(本示例中的小披露指示器)时,您的 calloutAccessoryControlTapped 被调用(在我下面的示例中,对某些细节 View Controller 执行 segue):

- (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control
{
    [self performSegueWithIdentifier:@"DetailsIphone" sender:view];
}

这是 iPhone 小屏幕上非常典型的用户体验。

但是,如果您不喜欢那个 UX 并且您不想要标准标注,而是希望发生其他事情,您可以定义您的 MKAnnotationView 以便标注不是显示,但是您拦截它并做其他事情(例如,在 iPad map 应用程序上,您可能会显示一些更复杂的弹出框而不是标准标注)。例如,您可以让您的 MKAnnotationView 不显示标注:

- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation
{
    if ([annotation isKindOfClass:[MKUserLocation class]])
        return nil;

    MKAnnotationView *annotationView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:@"loc"];
    annotationView.canShowCallout = NO;

    return annotationView;
}

但是您可以手动处理 didSelectAnnotationView 以检测用户何时点击了您的 MKAnnotationView,在此示例中显示了一个弹出框:

- (void)mapView:(MKMapView *)mapView didSelectAnnotationView:(MKAnnotationView *)view
{
    [mapView deselectAnnotation:view.annotation animated:YES];

    DetailsViewController *controller = [self.storyboard instantiateViewControllerWithIdentifier:@"DetailsPopover"];
    controller.annotation = view.annotation;
    self.popover = [[UIPopoverController alloc] initWithContentViewController:controller];
    self.popover.delegate = self;
    [self.popover presentPopoverFromRect:view.frame
                                  inView:view.superview
                permittedArrowDirections:UIPopoverArrowDirectionAny
                                animated:YES];
}

我在 my answer here 中包含了由上述代码生成的用户界面的一些屏幕快照.

https://stackoverflow.com/questions/15292318/

相关文章:

ios - 使用 Storyboard 的条件转场

objective-c - Interface Builder 中的 IBOutletCollect

objective-c - 如何编写 OS X Finder 插件

objective-c - 有没有一种简单的方法可以将 ISO8601 时间戳转换为格式化的 NSD

objective-c - iOS:如何将 UIViewAnimationCurve 转换为 UIV

objective-c - [NSNull null] 和 nil 有什么区别?

objective-c - 在 Objective C 中使用 extern

objective-c - 尝试标记应用程序图标,但未获得用户标记应用程序的权限 : iOS 8 X

ios - 使用自动布局,如何根据图像使 UIImageView 的大小动态变化?

ios - 字符串的静态 NSArray - 如何/在哪里初始化 View Controller