will this code when working show custom pins and logos or just 1 pin with custom logos? please see plist below, only error is Local declaration of mapView hides instance variabl
Add a stationIdKey
property to your custom annotation class MyAnnotation
and set the property when creating the annotation before calling addAnnotation
. For example:
//in MyAnnotation.h:
@property (nonatomic, copy) NSString *stationIdKey; //and release in dealloc
//in viewDidLoad before calling addAnnotation:
myAnnotation.stationIdKey = [note objectForKey:@"stationIdKey"];
Then in viewForAnnotation
, cast annotation
to the custom class and set the icon based on the stationIdKey
property:
NSString *iconFilename = @"";
MyAnnotation *myAnn = (MyAnnotation *)annotation;
if ([myAnn.stationIdKey isEqualToString:@"BP"])
iconFilename = @"bp-logo.png";
else
if ([myAnn.stationIdKey isEqualToString:@"Caltex"])
iconFilename = @"caltex.png";
else
if ([myAnn.stationIdKey isEqualToString:@"Shell"])
iconFilename = @"shell.png";
UIImageView *leftIconView = [[[UIImageView alloc]
initWithImage:[UIImage imageNamed:iconFilename]] autorelease];
(There are a few other issues with the code which I'll add details about later.)
viewForAnnotation
is only supposed to replace the part of the existing code that sets the leftCalloutAccessoryView
. It's not the whole delegate method.
The warning Control reaches end of non-void function
means that the replacement code is not returning a value even though the method is declared as returning a MKAnnotationView *
.
Below is the full method with other unrelated suggested changes:
-(MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id)annotation
{
if ([annotation isKindOfClass:[MyAnnotation class]])
{
static NSString *reuseId = @"customAnn";
MKAnnotationView *customAnnotationView = [mapView dequeueReusableAnnotationViewWithIdentifier:reuseId];
if (customAnnotationView == nil)
{
customAnnotationView = [[[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:reuseId] autorelease];
UIImage *pinImage = [UIImage imageNamed:@"pin-green.png"];
[customAnnotationView setImage:pinImage];
customAnnotationView.canShowCallout = YES;
UIButton *rightButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
customAnnotationView.rightCalloutAccessoryView = rightButton;
}
NSString *iconFilename = @"";
MyAnnotation *myAnn = (MyAnnotation *)annotation;
if ([myAnn.stationIdKey isEqualToString:@"BP"])
iconFilename = @"bp-logo.png";
else
if ([myAnn.stationIdKey isEqualToString:@"Caltex"])
iconFilename = @"caltex.png";
else
if ([myAnn.stationIdKey isEqualToString:@"Shell"])
iconFilename = @"shell.png";
UIImageView *leftIconView = [[[UIImageView alloc] initWithImage:[UIImage imageNamed:iconFilename]] autorelease];
customAnnotationView.leftCalloutAccessoryView = leftIconView;
customAnnotationView.annotation = annotation;
return customAnnotationView;
}
return nil;
}
I've added the following:
MyAnnotation
otherwise return nil
. So if you decide later to show other types of annotations like user location, it will still work.Removed the addTarget:action:
call for the rightButton
. I highly recommend you implement the map view's calloutAccessoryControlTapped
delegate method instead of a custom method. So instead of an annotationViewClick:
method, implement the delegate method, like this:
-(void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control
{
if ([view.annotation isKindOfClass:[MyAnnotation class]])
{
MyAnnotation *myAnn = (MyAnnotation *)view.annotation;
NSLog(@"callout button tapped for station id %@", myAnn.stationIdKey);
}
else
{
NSLog(@"callout button tapped for annotation %@", view.annotation);
}
}
Finally, in viewDidLoad
, you are creating the anns
array using alloc
but you are not calling release
which results in a memory leak.
Either replace the alloc+init of the anns
array with this auto-release version (recommended):
NSArray *anns = [NSArray arrayWithContentsOfFile:path];
or add this after the for-loop right before the end of the viewDidLoad
method:
[anns release];