4
votes

I am trying to perform the simple function of passing a custom property (placeId) through MKAnnotation. I have set everything up with a custom class called "MapViewAnnotation."

I would like to simply pass an additional value from the MapViewController to a DetailViewController when the user activates CalloutAccessoryControlTapped. I can get the title/subtitle to work, but I need to revise my code to allow for a custom variable.

I've been trying this for a while and can't get it to work properly. Any assistance would be great! Thank you!

MapViewAnnotation.h

@interface MapViewAnnotation : NSObject <MKAnnotation> {
    NSString *title;
    CLLocationCoordinate2D coordinate;
}

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

- (id)initWithTitle:(NSString *)ttl andCoordinate:(CLLocationCoordinate2D)c2d;

@end

MapViewAnnotation.m

@implementation MapViewAnnotation

@synthesize title, coordinate, subtitle;

- (id)initWithTitle:(NSString *)ttl andCoordinate:(CLLocationCoordinate2D)c2d {
    title = ttl;
    coordinate = c2d;
    subtitle = @"Test Subtitle";
    return self;
}

@end

Annotation Creation in MapViewController.m - Here you can see that I am using the subtitle to pass the placeId (bottom line)

location.latitude = [dictionary[@"placeLatitude"] doubleValue];
location.longitude = [dictionary[@"placeLongitude"] doubleValue];    

newAnnotation = [[MapViewAnnotation alloc] initWithTitle:dictionary[@"placeName"]
                                               andCoordinate:location];

newAnnotation.subtitle = dictionary[@"placeId"];

CalloutAccessoryControlTapped in MapViewController.m - here you can see that I am saving the placeId to NSUserDefaults

- (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view 
calloutAccessoryControlTapped:(UIControl *)control
{
    NSString *passedId = view.annotation.subtitle;
    [[NSUserDefaults standardUserDefaults]
    setObject:passedId forKey:@"passedId"];
    [[NSUserDefaults standardUserDefaults] synchronize];
}
1
can you explain better what's the problem? Are you getting an exception somewhere? is passedId nil when you try to retrieve it? - The dude
The code displayed above works fine - but it makes the placeId visible to the user as the subtitle of the annotation. I would like to make the placeId invisible by using a custom class. I've been trying again and again but can't get it right. - Brandon

1 Answers

5
votes

Why don't you add a new property in your custom map view annotation? In MapViewAnnotation.h add

@property (nonatomic, strong) NSString *passedID;

Then, in your annotation creation in the viewcontroller, you set that property instead of setting the subtitle:

newAnnotation = [[MapViewAnnotation alloc] initWithTitle:dictionary[@"placeName"]
                                               andCoordinate:location];

newAnnotation.passedID = dictionary[@"placeId"];

Finally, in your CalloutAccessoryControlTapped, you cast the MapViewAnnotation to your custom class, and then access the passedID property, instead of the subtitle property:

- (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view 
calloutAccessoryControlTapped:(UIControl *)control
{
    NSString *passedId = ((MapViewAnnotation*)view.annotation).passedID;
    [[NSUserDefaults standardUserDefaults]
    setObject:passedId forKey:@"passedId"];
    [[NSUserDefaults standardUserDefaults] synchronize];
}