简体   繁体   中英

Create custom callout for an annotation

In iOS6 I am trying to create a custom callout for an annotation that will contain detail like, image, title, description etc. I have seen relevant posts here but aren't what I am looking for. In my app, when you are selecting an annotation, you have a choice of 4 buttons. Now I am trying to create the option for 4th button which is the detailed callout.

I have create a UIView class that represents the custom callout.

EDIT:

After help from Live2Enjoy7 I have modified my code as below.

BuildingViewController.m

- (void)MapMenu:(MapMenu *)menu didSelectButton:(NSInteger)index{

    if (index == 3) {

        image = [UIImage imageWithData: [NSData dataWithContentsOfURL:url]];
        _buildingShowCallout = YES;
        [parentView removeAnnotation:self];
        [parentView addAnnotation:self];
    }
}

If user press the button, this method, create new image (using url link), setting the _buildingShowCallout = YES and finally removing and adding again the selected annotation in order to make viewForAnnotation method to act.

In my MapViewController.m

- (MKAnnotationView *)mapView:(MKMapView *)_mapView viewForAnnotation:(id<MKAnnotation>)annotation{

    if ([annotation isKindOfClass:[MKUserLocation class]]) {
        return nil;
    }

    static NSString *identifier = @"MyAnnotation";
    MKPinAnnotationView *annotationView = (MKPinAnnotationView *) [_mapView dequeueReusableAnnotationViewWithIdentifier:identifier];

    BuildingViewController* building = (BuildingViewController*) annotation;

    // If a new annotation is created
    if (annotationView == nil) {

        annotationView = [[MKPinAnnotationView alloc] initWithAnnotation:building reuseIdentifier:identifier];

        if (building.buildingShowCallout) {// Create the custom callout
            BuildingCallOut* buildingCallout = [[BuildingCallOut alloc]initWithFrame:CGRectMake(0, 0, 200, 150)];
            [buildingCallout showCallout:building];
            [annotationView addSubview:buildingCallout];//add the new callout as subview of the selected annotation.
        }

    } else{

        annotationView.annotation = annotation;

        if (building.buildingShowCallout) {// Create the custom callout
            BuildingCallOut* buildingCallout = [[BuildingCallOut alloc]initWithFrame:CGRectMake(0, 0, 200, 150)];
            [buildingCallout showCallout:building];
            [annotationView addSubview:buildingCallout];//add the new callout as subview of the selected annotation.
        }
    }

    return annotationView;
}

That's working fine BUT now I have one new problem.

  1. If you select to see a callout for one annotation and then select to see a callout for another annotation, the previous one stays on the map. How I can solve this?

Screenshot ![enter image description here][1]

As you can see.. the previous callout on the top of the screen remains when I am calling the new one at the bottom. Struggling to find where to put the "disappear" line. Thanks in advance

I'm guessing your BuildingViewController is your MapViewController.

You want to declare it as an MKMapViewDelegate in your header. This will give you access to several methods that will allow you to change the view of the annotation that appears and even the pin.

First, import MapKit/MapKit.h and UIKit/UIKit.h if you aren't already.

Second, declare that your BuildingViewController conforms to the MKMapViewDelegate protocol (as stated above).

Third, declare your BuildingViewController as the map view's delegate in ViewDidLoad like:

self.mapView.delegate=self; //assuming that the you have a MKMapView named MapView in your layout

Fourth, implement these protocol methods:

-(MKAnnotationView*)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation;

-(void)mapView:(MKMapView *)mapView didSelectAnnotationView:(MKAnnotationView *)view;

First method allows you to set right and left call out accessories as well as modify bunch of other things (this is where you want to do you CGRectMakes).

In second method, you decide what data actually gets displayed in the annotation view.

Search the documentation for MKMapViewDelegate --> here

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM