如何从地图图钉上的披露按钮调用 segue?

Posted

技术标签:

【中文标题】如何从地图图钉上的披露按钮调用 segue?【英文标题】:How to call a segue from a disclosure button on a map pin? 【发布时间】:2013-05-29 23:18:46 【问题描述】:

我有一个在地图视图上绘制图钉的应用。

每个图钉都使用此代码显示一个详细信息披露按钮,点击该按钮时会调用 showDetail 方法,该方法随后会调用 prepareForSegue 方法。我认为这里有很多额外的工作。

我应该消除 showDetail 并只调用 prepareForSegue 方法吗?但是我将如何传递 MyLocation 对象?

代码如下:

- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation 
    static NSString *identifier = @"MyLocation";
    if ([annotation isKindOfClass:[MyLocation class]]) 

        //test if mapviewnil
        if (_mapView == nil) 
            NSLog(@"NIL");
        
        MKPinAnnotationView *annotationView = (MKPinAnnotationView *) [_mapView dequeueReusableAnnotationViewWithIdentifier:identifier];
        if (annotationView == nil) 
            annotationView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:identifier];
         else 
            annotationView.annotation = annotation;
        

        annotationView.enabled = YES;
        annotationView.canShowCallout = YES;
        annotationView.image=[UIImage imageNamed:@"locale.png"];


        //instatiate a detail-disclosure button and set it to appear on right side of annotation
        UIButton *infoButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
        [infoButton addTarget:self action:@selector(showDetailView:annotation:) forControlEvents:UIControlEventTouchUpInside];
        annotationView.rightCalloutAccessoryView = infoButton;

        return annotationView;
    

    return nil;


-(void)showDetailView:(id <MKAnnotation>)annotation

    //Set the data
    MyLocation *sendingLocation = annotation;

    DetailViewController *destinationViewController = segue.destinationViewController;
    destinationViewController.receivedLocation = sendingLocation;
    [self performSegueWithIdentifier: @"DetailVC" sender: self];



- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
    if ([segue.identifier isEqualToString:@"DetailVC"]) 
        NSLog(@"DetailVC called");
     else 
        NSLog(@"PFS:something else");
    

提前谢谢!

【问题讨论】:

您的showDetailView 正在尝试使用segue.destinationViewController,但在prepareForSegue 之前您不能这样做。但是您可能根本不需要showDetailView,而应该只使用标准的calloutAccessoryControlTapped 委托方法,如下所述。 【参考方案1】:

通常你不会为按钮添加目标,而只是设置rightCalloutAccessoryView(就像你一样)然后编写一个calloutAccessoryControlTapped方法,例如:

- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation 
    static NSString *identifier = @"MyLocation";
    if ([annotation isKindOfClass:[MyLocation class]]) 

        MKPinAnnotationView *annotationView = (MKPinAnnotationView *) [mapView dequeueReusableAnnotationViewWithIdentifier:identifier];
        if (annotationView == nil) 
            annotationView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:identifier];
            annotationView.enabled = YES;
            annotationView.canShowCallout = YES;
            annotationView.image = [UIImage imageNamed:@"locale.png"]; // since you're setting the image, you could use MKAnnotationView instead of MKPinAnnotationView
            annotationView.rightCalloutAccessoryView = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
         else 
            annotationView.annotation = annotation;
        

        return annotationView;
    

    return nil;


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

    if (![view.annotation isKindOfClass:[MyLocation class]])
        return;

    // use the annotation view as the sender

    [self performSegueWithIdentifier:@"DetailVC" sender:view];


- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(MKAnnotationView *)sender

    if ([segue.identifier isEqualToString:@"DetailVC"]) 
    
        DetailViewController *destinationViewController = segue.destinationViewController;

        // grab the annotation from the sender

        destinationViewController.receivedLocation = sender.annotation;
     else 
        NSLog(@"PFS:something else");
    

【讨论】:

注意,我稍微简化了viewForAnnotation。不仅摆脱了 target 的东西,而且也不需要引用你的类 ivar,因为 mapView 是方法的参数。

以上是关于如何从地图图钉上的披露按钮调用 segue?的主要内容,如果未能解决你的问题,请参考以下文章

从详细信息披露按钮 segue 传递对象

Swift - 从地图注释中执行 Segue

从给定位置拖动图钉

如何使用相机谷歌地图 xcode 移动标记(图钉)

详细信息披露按钮和 Segues

如何在 SwiftUI 的新地图视图中制作可点击的图钉?