I have the following files:
annotation.h:
#import <Foundation/Foundation.h>
#import <MapKit/MapKit.h>
@interface annotation : NSObject <MKAnnotation>
@property(nonatomic, assign) CLLocationCoordinate2D coordinate;
@property(nonatomic, copy) NSString *title;
@property(nonatomic, copy) NSString *subtitle;
@end
annotation.m:
#import "annotation.h"
@implementation annotation
@synthesize coordinate, title, subtitle;
@end
And in the main code, which takes in an NSURL
found elsewhere:
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
[spinner stopAnimating];
// json parsing
results = [NSJSONSerialization JSONObjectWithData:data options:nil error:nil];
NSMutableArray * locations = [[NSMutableArray alloc] init];
CLLocationCoordinate2D location;
annotation * myAnn;
NSArray *pins = mapView.annotations;
if ([pins count])
{
[mapView removeAnnotations:pins];
}
/* loop through the array, each key in the array has a JSON String with format:
* title <- string
* strap <- string
* id <- int
* date <- date
* lat <- floating point double
* long <- floating point double
* link <- string
*/
int i;
for (i = 0; i < [results count]; i++) {
//NSLog(@"Result: %i = %@", i, results[i]);
//NSLog(@"%@",[[results objectAtIndex:i] objectForKey:@"long"]);
myAnn = [[annotation alloc] init];
location.latitude = (double)[[[results objectAtIndex:i] objectForKey:@"lat"] doubleValue];
location.longitude = (double)[[[results objectAtIndex:i] objectForKey:@"long"] doubleValue];
myAnn.coordinate = location;
myAnn.title = [[results objectAtIndex:i] objectForKey:@"title"];
myAnn.subtitle = [[results objectAtIndex:i] objectForKey:@"strap"];
[locations addObject:myAnn];
//NSLog(@"%i", [[results objectAtIndex:i] objectForKey:@"lat"]);
}
[self.mapView addAnnotations:locations];
Previous things I have looked at for this say that I need to use MKAnnotationView
as opposed to MKPinAnnotationView
but as you can see I do not use either, is it possible for me to use custom images for the pins that are dropped on the screen.
You (a) make sure to define your view controller to be the delegate
for your MKMapView
; and (b) implement viewForAnnotation
, e.g.:
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation {
if ([annotation isKindOfClass:[MKUserLocation class]]) {
return nil;
}
if ([annotation isKindOfClass:[CustomAnnotation class]]) {
static NSString * const identifier = @"MyCustomAnnotation";
MKAnnotationView* annotationView = [mapView dequeueReusableAnnotationViewWithIdentifier:identifier];
if (annotationView) {
annotationView.annotation = annotation;
} else {
annotationView = [[MKAnnotationView alloc] initWithAnnotation:annotation
reuseIdentifier:identifier];
}
// set your annotationView properties
annotationView.image = [UIImage imageNamed:@"Your image here"];
annotationView.canShowCallout = YES;
// if you add QuartzCore to your project, you can set shadows for your image, too
//
// [annotationView.layer setShadowColor:[UIColor blackColor].CGColor];
// [annotationView.layer setShadowOpacity:1.0f];
// [annotationView.layer setShadowRadius:5.0f];
// [annotationView.layer setShadowOffset:CGSizeMake(0, 0)];
// [annotationView setBackgroundColor:[UIColor whiteColor]];
return annotationView;
}
return nil;
}
By the way, in my example above, I changed the name of your annotation
class to CustomAnnotation
. annotation
is a horrible name for a class because (a) it doesn't follow class naming conventions of upper case first letter; and (b) it's identical to the variable name, annotation
, that many MKMapViewDelegate
methods will use by default.