Issue with Map Annotation and MKMapView in iOS 4.2?

守給你的承諾、 提交于 2019-11-29 15:17:09

In checkButtonTapped, the annotation is being identified using the button's tag. The button's tag is set in viewForAnnotation by calling the custom method getPinID.

The button tag is used as the index into the mapView annotations array. It's not clear how the getPinID method figures out what index it is at in the mapView's annotations array. I'm not sure it's wise to assume an annotation is going to be at a specific index in the array. Even if mapView doesn't shuffle the annotations around, your app might be constantly adding and removing annotations.

Because you are assigning the button as a callout accessory in the annotation view, rather than using a button tag to identify the annotation, you can use the mapView's own mapView:annotationView:calloutAccessoryControlTapped: delegate method.

Instead of doing addTarget on the button and having it call your custom method, remove the call to addTarget and implement calloutAccessoryControlTapped.

In calloutAccessoryControlTapped, you can directly access the annotation using view.annotation. You can also easily check if the annotation is the "user location":

 - (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control
    {
        if (view.annotation == mapView.userLocation)
            return;

        buttonDetail = (MyCustomAnnotationClass *)view.annotation;

        //show detail view using buttonDetail...
    }

Additionally, in viewForAnnotation, you are creating a button every time even if the view is being re-used. So a re-used annotation view probably ends up getting multiple buttons on top of each other. The button should only be created and set in the if(pinView == nil) section.

If anyone would care to see what I am using now (and it is working) ...

- (MKPinAnnotationView *)mapView:(MKMapView *)eMapView viewForAnnotation:(id <MKAnnotation>)annotation {

    MKPinAnnotationView *pinView = (MKPinAnnotationView *)[eMapView dequeueReusableAnnotationViewWithIdentifier:@"Pin"];

    if(pinView == nil) {

        pinView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:@"Pin"];
        pinView.frame = CGRectMake(0, 0, 25, 25);

    } else {

        pinView.annotation = annotation;

    }   

    // Set up the Right callout
    UIButton *myDetailButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
    myDetailButton.frame = CGRectMake(0, 0, 23, 23);
    myDetailButton.contentVerticalAlignment = UIControlContentVerticalAlignmentCenter;
    myDetailButton.contentHorizontalAlignment = UIControlContentHorizontalAlignmentCenter;

    pinView.rightCalloutAccessoryView = myDetailButton;

    pinView.animatesDrop = YES;

    // Set to show a callout on the pin
    pinView.canShowCallout = YES;

    return pinView;
}

// Added this at the suggestion of aBitObvious on StackOverflow - 120810
- (void)mapView:(MKMapView *)eMapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control {

    if (view.annotation == eMapView.userLocation)
        return;

    if (self.showDetailView == nil) {

        DetailData *tmpViewController = [[DetailData alloc] initWithNibName:@"DetailData" bundle:nil];
        self.showDetailView = tmpViewController;
        [tmpViewController release];

    }

    buttonDetail = (MyCustomAnnotationClass *)view.annotation;

    NSMutableArray *tmpArray = [NSMutableArray arrayWithObjects: [buttonDetail getDataI], [buttonDetail getDataII], [buttonDetail getDataIII], [buttonDetail getDataIV], [buttonDetail getDataV], nil];

    self.showDetailView.eventData = [[NSMutableArray alloc] initWithArray:tmpArray copyItems:YES];

    [self.navigationController pushViewController:self.showDetailView animated:YES];

    [self.showDetailView.eventData release];

}

Thanks again!

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!