简体   繁体   中英

How to add callout into individual annotation in map view

I'm trying to set each annotation with different callout detail info.

Currently when I click on any annotation location, it shows all the callout info.

#import "AnnotationViewController.h"
#import "Annotation.h"

@implementation AnnotationViewController
@synthesize mapView;

-(void)viewDidLoad {

    [super viewDidLoad];
    [mapView setMapType:MKMapTypeStandard];
    [mapView setZoomEnabled:YES];
    [mapView setScrollEnabled:YES];
    [mapView setDelegate:self];

    MKCoordinateRegion TT = { {0.0, 0.0} , {0.0, 0.0} };
    TT.center.latitude = 43.65343;
    TT.center.longitude = -79.396311;
    TT.span.longitudeDelta = 0.02f;
    TT.span.latitudeDelta = 0.02f;
    [mapView setRegion:TT animated:YES];

    Annotation *ann1 = [[Annotation alloc] init];
    ann1.title = @"Annotation 01";
    ann1.subtitle = @"Message 01";
    ann1.coordinate = TT.center;
    [mapView addAnnotation:ann1];

    MKCoordinateRegion TTY = { {0.0, 0.0} , {0.0, 0.0} };
    TTY.center.latitude = 43.76919;
    TTY.center.longitude = -79.41245;
    TTY.span.longitudeDelta = 0.02f;
    TTY.span.latitudeDelta = 0.02f;
    [mapView setRegion:TTY animated:YES];

    Annotation *ann2 = [[Annotation alloc] init];
    ann2.title = @"Annotation 02";
    ann2.subtitle = @"Message 02";
    ann2.coordinate = TTY.center;
    [mapView addAnnotation:ann2];

}


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

    UIImageView *imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"GPSicon.png"]];
    view.leftCalloutAccessoryView = imageView;
    view.rightCalloutAccessoryView = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];

    return view;

}

- (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control
{
    NSString *msg = [@"Location 01" stringByAppendingFormat:@"Opening 01"];
    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Plaza 01" message:msg delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil];
    [alert show];

    NSString *msg02 = [@"Location 02" stringByAppendingFormat:@"Opening 02"];
    UIAlertView *alert02 = [[UIAlertView alloc] initWithTitle:@"Plaza 02" message:msg02 delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil];
    [alert02 show];

}


-(void)button:(id)sender {

    NSLog(@"Button action");

}

- (void)dealloc
{

}

- (void)didReceiveMemoryWarning
{
    // Releases the view if it doesn't have a superview.
    [super didReceiveMemoryWarning];

    // Release any cached data, images, etc that aren't in use.
}

#pragma mark - View lifecycle

/*
 // Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
 - (void)viewDidLoad
 {
 [super viewDidLoad];
 }
 */

- (void)viewDidUnload
{
    [super viewDidUnload];
    // Release any retained subviews of the main view.
    // e.g. self.myOutlet = nil;
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    // Return YES for supported orientations
    return (interfaceOrientation == UIInterfaceOrientationPortrait);
}

end

So this is what's happening: When I click on "Annotation 01" the bubble will appear. But when I click on the callout "detail icon", it will popup both Location 01 & Location 2 titles.


Thanks Anna for you help. But I still get 2 callouts when i check one annotation. This is the code now..

#import "AnnotationViewController.h"
#import "Annotation.h"

@implementation AnnotationViewController
@synthesize mapView;

-(void)viewDidLoad {

[super viewDidLoad];
[mapView setMapType:MKMapTypeStandard];
[mapView setZoomEnabled:YES];
[mapView setScrollEnabled:YES];
[mapView setDelegate:self];

MKCoordinateRegion TT = { {0.0, 0.0} , {0.0, 0.0} };
TT.center.latitude = 43.65343;
TT.center.longitude = -79.396311;
TT.span.longitudeDelta = 0.02f;
TT.span.latitudeDelta = 0.02f;
[mapView setRegion:TT animated:YES];

Annotation *ann1 = [[Annotation alloc] init];
ann1.title = @"Annotation 01";
ann1.subtitle = @"Message 01";
ann1.coordinate = TT.center;
[mapView addAnnotation:ann1];

MKCoordinateRegion TTY = { {0.0, 0.0} , {0.0, 0.0} };
TTY.center.latitude = 43.76919;
TTY.center.longitude = -79.41245;
TTY.span.longitudeDelta = 0.02f;
TTY.span.latitudeDelta = 0.02f;
[mapView setRegion:TTY animated:YES];

Annotation *ann2 = [[Annotation alloc] init];
ann2.title = @"Annotation 02";
ann2.subtitle = @"Message 02";
ann2.coordinate = TTY.center;
[mapView addAnnotation:ann2];

}


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

UIImageView *imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"GPSicon.png"]];
view.leftCalloutAccessoryView = imageView;
view.rightCalloutAccessoryView = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];

return view;

}

- (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control
{
//first make sure the annotation is our custom class...
if ([view.annotation isKindOfClass:[Annotation class]])
{
    //cast the object to our custom class...
    Annotation *ann1 = (Annotation *)view.annotation;

    //show one alert view with title set to annotation's title
    //and message set to annotation's subtitle...
    UIAlertView *alert = [[UIAlertView alloc] 
                             initWithTitle:ann1.title 
                             message:ann1.subtitle 
                             delegate:self 
                             cancelButtonTitle:@"OK" 
                             otherButtonTitles:nil];

    [alert show];
}
    //first make sure the annotation is our custom class...
if ([view.annotation isKindOfClass:[Annotation class]])
{
    //cast the object to our custom class...
    Annotation *ann2 = (Annotation *)view.annotation;

    //show one alert view with title set to annotation's title
    //and message set to annotation's subtitle...
    UIAlertView *alert2 = [[UIAlertView alloc] 
                             initWithTitle:ann2.title 
                             message:ann2.subtitle 
                             delegate:self 
                             cancelButtonTitle:@"OK" 
                             otherButtonTitles:nil];

    [alert show];
}
}


-(void)button:(id)sender {

NSLog(@"Button action");

}

- (void)dealloc
{

}

- (void)didReceiveMemoryWarning
{
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];

// Release any cached data, images, etc that aren't in use.
}

#pragma mark - View lifecycle

/*
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad
{
[super viewDidLoad];
}
*/

- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}

end

My Annotation.m file code

#import "Annotation.h"


@implementation Annotation
@synthesize coordinate, title, subtitle;

-(void)dealloc {


}

@end

My Annotation.h file code

#import <Foundation/Foundation.h>
#import <MapKit/MKAnnotation.h>


@interface Annotation : NSObject <MKAnnotation> {

CLLocationCoordinate2D coordinate;
NSString *title;
NSString *subtitle;

}

@property(nonatomic, assign) CLLocationCoordinate2D coordinate;
@property(nonatomic, copy) NSString *title;
@property(nonatomic, copy) NSString *subtitle;

@end

Do i have to make alot of h/m files for each Annotation to make the callout different? im just stomp at this point. any guesses would be great, thanks!

In calloutAccessoryControlTapped , the code is showing two alert views with hard-coded text for the title and message one after the other. So that's what you get obviously.

In the calloutAccessoryControlTapped method, the annotation object whose callout button was tapped is available via view.annotation .

The view parameter is the MKAnnotationView which has an annotation property that points to its related annotation.

So change the code to show only one alert view and with the title and message based on the properties of the annotation object.

It's also a good idea to check the class of the annotation to make sure it's the type of annotation you're expecting.

For example:

- (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control
{
    //first make sure the annotation is our custom class...
    if ([view.annotation isKindOfClass:[Annotation class]])
    {
        //cast the object to our custom class...
        Annotation *ann = (Annotation *)view.annotation;

        //show one alert view with title set to annotation's title
        //and message set to annotation's subtitle...
        UIAlertView *alert = [[UIAlertView alloc] 
                                 initWithTitle:ann.title 
                                 message:ann.subtitle 
                                 delegate:self 
                                 cancelButtonTitle:@"OK" 
                                 otherButtonTitles:nil];

        [alert show];
    }
}

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