允许在没有标注附件视图的情况下点击注释标注上的任何位置

bde*_*ham 19 mkmapview ios

我有一个地图视图,添加注释或多或少像这样:

- (MKAnnotationView *)mapView:(MKMapView *)mapView
            viewForAnnotation:(id <MKAnnotation>) annotation
{
    MKAnnotationView *annotationView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation
                                                                       reuseIdentifier:@"MKPinAnnotationView"];
    annotationView.canShowCallout = YES;

    UIButton *detailButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
    [detailButton addTarget:self
                     action:@selector(handleButtonAction)
           forControlEvents:UIControlEventTouchUpInside];
    annotationView.rightCalloutAccessoryView = detailButton;

    return annotationView;
}
Run Code Online (Sandbox Code Playgroud)

在iOS 7中,这会在标注的右侧放置一个"i"图标.点击图标触发mapView:annotationView:calloutAccessoryControlTapped:(在代理上)和handleButtonAction:(在自己上).不过,我最近意识到你也可以点击标注上的其他任何地方,并触发相同的两种方法.

使用类型的按钮会发生这种情况,UIButtonTypeDetailDisclosure但似乎没有UIButtonTypeCustom按钮发生.当没有附件视图时点击标注时,也不会触发委托方法.(当然,这种行为并不令人惊讶;令人惊讶的是,如果附件视图是详细信息泄露按钮,那么无论您是点击按钮本身还是只是点击标注中的其他位置,这两种方法都会触发.)

我想摆脱标注中的按钮 - 或者至少用显示我自己的图像而不是股票"i"图标的按钮替换它 - 同时仍允许用户点击标注上的任何地方以触发我的动作.这可能吗?我没有看到MKMapViewDelegate与"callout tapped"对应的方法.

vok*_*lam 29

尝试为按钮设置自定义图像而不更改UIButtonTypeDetailDisclosure类型.

UIButton *detailButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];        
[detailButton setImage:[UIImage imageNamed:@"icon"] forState:UIControlStateNormal];
Run Code Online (Sandbox Code Playgroud)

对于iOS7及更高版本,此图像将默认着色.如果要保留原始图标,请使用以下内容

[[UIImage imageNamed:@"icon"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal]
Run Code Online (Sandbox Code Playgroud)

或者,如果你想删除图标

[detailButton setImage:[UIImage new] forState:UIControlStateNormal];
Run Code Online (Sandbox Code Playgroud)


小智 9

挖掘标注按钮,用户点击了注解视图后,加UITapGestureRecognizerdidSelectAnnotationView.这样,您可以在不需要附件视图的情况下实现对标注的点击.

然后,您可以从发件人处获取注释对象以进行进一步操作.

- (void)mapView:(MKMapView *)mapView didSelectAnnotationView:(MKAnnotationView *)view
{
    UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self  action:@selector(calloutTapped:)];
    [view addGestureRecognizer:tapGesture];
}

-(void)calloutTapped:(UITapGestureRecognizer *) sender
{
    NSLog(@"Callout was tapped");

    MKAnnotationView *view = (MKAnnotationView*)sender.view;
    id <MKAnnotation> annotation = [view annotation];
    if ([annotation isKindOfClass:[MKPointAnnotation class]])
    {
        [self performSegueWithIdentifier:@"annotationDetailSegue" sender:annotation];
    }
}
Run Code Online (Sandbox Code Playgroud)


Axe*_*min 7

Dhanu A在Swift 3中的解决方案:

func mapView(mapView: MKMapView, didSelectAnnotationView view:MKAnnotationView) {
    let tapGesture = UITapGestureRecognizer(target:self,  action:#selector(calloutTapped(sender:)))
    view.addGestureRecognizer(tapGesture)
}

func mapView(mapView: MKMapView, didDeselectAnnotationView view: MKAnnotationView) {
    view.removeGestureRecognizer(view.gestureRecognizers!.first!)
}

func calloutTapped(sender:UITapGestureRecognizer) {
    let view = sender.view as! MKAnnotationView
    if let annotation = view.annotation as? MKPointAnnotation {
        performSegue(withIdentifier: "annotationDetailSegue", sender: annotation)
    }
}
Run Code Online (Sandbox Code Playgroud)