Ios MKMapView MKPointAnnotation tap事件

Ios MKMapView MKPointAnnotation tap事件,ios,objective-c,mkmapview,mapkit,mkannotation,Ios,Objective C,Mkmapview,Mapkit,Mkannotation,我有一个注释列表(MKPointAnnotation)。我有一个用于整个视图的UIViewController,MKMapView实现控制器,我认为它对于检测用户与地图的交互非常有用,我自己的MKPointAnnotation实现(子类)控制器告诉如何显示注释 然而,我被用户检测到的点击事件震惊了 谷歌告诉我,我必须通过实现以下功能来做一些事情 - (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view

我有一个注释列表(MKPointAnnotation)。我有一个用于整个视图的UIViewController,MKMapView实现控制器,我认为它对于检测用户与地图的交互非常有用,我自己的MKPointAnnotation实现(子类)控制器告诉如何显示注释

然而,我被用户检测到的点击事件震惊了

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

- (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control
我还必须在实现MapViewDelegate(协议)的某个类中实现这一点

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


抱歉这么大惊小怪

在此方法中添加按钮

-(MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation 
{
  pinView.rightCalloutAccessoryView = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
  pinView.canShowCallout = YES;
}

Then callout method
- (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control
{
      InfoView *infoView = [[InfoView alloc]initWithNibName:@"InfoView" bundle:nil];
        [self.navigationController pushViewController:infoView animated:YES];

} 
-(MKAnnotationView*)地图视图:(MKMapView*)地图视图注释:(id)注释
{
pinView.rightCalloutAccessoryView=[UIButton Button类型为:UIButtonTypedTailDisplay];
pinView.canShowCallout=是;
}
然后调用方法
-(无效)地图视图:(MKMapView*)地图视图注释视图:(MKAnnotationView*)视图调用访问控制点击:(UIControl*)控制
{
InfoView*InfoView=[[InfoView alloc]initWithNibName:@“InfoView”捆绑包:nil];
[self.navigationController pushViewController:infoView动画:是];
} 

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

- (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;
}
这是iPhone小屏幕上非常典型的用户体验

但是,如果您不喜欢该用户体验,并且不希望使用标准调用,而是希望发生其他事情,则可以定义
MKAnnotationView
,以便不显示调用,而是截取它并执行其他操作(例如,在iPad地图应用程序上,您可能会显示一些更复杂的弹出窗口,而不是标准的标注)。例如,您可以让您的
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;
}

我将上述代码生成的用户界面的一些屏幕快照包括在中。

Swift 3的Robs示例:

class MapViewController: UIViewController
{
    override func viewDidLoad()
    {
        super.viewDidLoad()

        // Create map view in storyboard
        view.delegate = self
    }
}

extension MapViewController: MKMapViewDelegate
{
    func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView?
    {
        let annotationView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: "annotationView")
        annotationView.canShowCallout = true
        annotationView.rightCalloutAccessoryView = UIButton.init(type: UIButtonType.detailDisclosure)

        return annotationView
    }

    func mapView(_ mapView: MKMapView, annotationView view: MKAnnotationView, calloutAccessoryControlTapped control: UIControl)
    {
        guard let annotation = view.annotation else
        {
            return
        }

        let urlString = "http://maps.apple.com/?sll=\(annotation.coordinate.latitude),\(annotation.coordinate.longitude)"
        guard let url = URL(string: urlString) else
        {
            return
        }

        UIApplication.shared.openURL(url)
    }
}

您必须为每个批注设置标记,以便当您点击任何批注时,您可以从批注获取标记并调用生成这些批注的数组的相应数据成员。-(无效)mapView:(MKMapView*)mapView annotationView:(MKAnnotationView*)view calloutAccessoryControlTapped:(UIControl*)control{NSLog(@“got here”);}…..我把这个函数放在所有三个控制器中,但没有一个被调用….你能告诉我应该在哪里定义这个函数吗?你能告诉我应该在哪里实现这些吗?MKMapView控制器?@Ravivoda yaa被强加在MapViewpart的编码上。任何其他问题你可以问我:)@Ravivoda您应该在
MKMapView
委托中实现这些。您经常为
MKMapView
指定
委托作为包含地图视图的视图的视图控制器。但是不要忘了设置地图视图的委托(在代码中或通过界面生成器).Hi,这似乎对iOS7及以上版本不起作用。有任何关于iOS8修复的建议吗?@roshi我对它进行了测试,在iOS 8中效果很好。你是否设置了地图视图的委托?如果你仍然有问题,也许可以在s.O.上发布你自己的问题。详细的代码示例,对你尝试过的内容的描述,等等。@Rob你能看看吗&帮我解决我的问题issue@Rob这会将我的用户位置变成pin码。我可以防止吗?以及防止它被点击吗?@user1282637检查
如果([annotation isKindOfClass:[MKUserLocation class]])…
,如上面修订的示例代码段所示。
- (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];
}
class MapViewController: UIViewController
{
    override func viewDidLoad()
    {
        super.viewDidLoad()

        // Create map view in storyboard
        view.delegate = self
    }
}

extension MapViewController: MKMapViewDelegate
{
    func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView?
    {
        let annotationView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: "annotationView")
        annotationView.canShowCallout = true
        annotationView.rightCalloutAccessoryView = UIButton.init(type: UIButtonType.detailDisclosure)

        return annotationView
    }

    func mapView(_ mapView: MKMapView, annotationView view: MKAnnotationView, calloutAccessoryControlTapped control: UIControl)
    {
        guard let annotation = view.annotation else
        {
            return
        }

        let urlString = "http://maps.apple.com/?sll=\(annotation.coordinate.latitude),\(annotation.coordinate.longitude)"
        guard let url = URL(string: urlString) else
        {
            return
        }

        UIApplication.shared.openURL(url)
    }
}