I am now working on a mapView. This is the scenario:
- All annotations are coming from JSON objects (MySQL tables).
- Annotations are grouped by source table:
- Table 1-> Ofertas, Table 2-> Cursos, Table 3-> Eventos.
- Initially there is shown a map region which is big enough to show later all annotations.
- There is a UISegmentedControll to let the user select which annotations group should be shown.
At this app state, I will need to make the following updates:
- Each annotation group should have a different pin colour.
This is the method I am using to draw the annotations to the mapView depending on the selected index:
- (IBAction)changeOpcion:(id)sender{
if(miControl.selectedSegmentIndex == 0)
{
//[mapView_ clear];
[self removeAllPinsButUserLocation2];
NSLog(@"********0");
for ( int i=0;i<[categorias count];i++){
int grupo = [[[categorias objectAtIndex:i] objectForKey:@"procedencia"] integerValue];
if (grupo == 1){
double latitud = [[[categorias objectAtIndex:i] objectForKey:@"latitud"] doubleValue];
double longitud = [[[categorias objectAtIndex:i] objectForKey:@"longitud"]doubleValue];
CLLocationCoordinate2D lugar;
lugar.latitude = latitud;
lugar.longitude = longitud;
NSString *nombre = [[categorias objectAtIndex:i] objectForKey:@"titulo"];
NSString *direccion = [[categorias objectAtIndex:i] objectForKey:@"direccion"];
CLLocationCoordinate2D coordinate3;
coordinate3.latitude = latitud;
coordinate3.longitude = longitud;
myAnnotation *annotation3 = [[myAnnotation alloc] initWithCoordinate:coordinate3 title:nombre];
[self.mapView addAnnotation:annotation3];
}
}
}
else if(miControl.selectedSegmentIndex == 1)
{
[self removeAllPinsButUserLocation2];
for ( int i=0;i<[categorias count];i++){
int grupo = [[[categorias objectAtIndex:i] objectForKey:@"procedencia"] integerValue];
if (grupo == 2){
double latitud = [[[categorias objectAtIndex:i] objectForKey:@"latitud"] doubleValue];
double longitud = [[[categorias objectAtIndex:i] objectForKey:@"longitud"]doubleValue];
CLLocationCoordinate2D lugar;
lugar.latitude = latitud;
lugar.longitude = longitud;
NSString *nombre = [[categorias objectAtIndex:i] objectForKey:@"titulo"];
NSString *direccion = [[categorias objectAtIndex:i] objectForKey:@"direccion"];
CLLocationCoordinate2D coordinate3;
coordinate3.latitude = latitud;
coordinate3.longitude = longitud;
myAnnotation *annotation3 = [[myAnnotation alloc] initWithCoordinate:coordinate3 title:nombre];
[self.mapView addAnnotation:annotation3];
}
}
//action for the second button
}
else if(miControl.selectedSegmentIndex == 2)
{
[self removeAllPinsButUserLocation2];
for ( int i=0;i<[categorias count];i++){
int grupo = [[[categorias objectAtIndex:i] objectForKey:@"procedencia"] integerValue];
if (grupo == 3){
double latitud = [[[categorias objectAtIndex:i] objectForKey:@"latitud"] doubleValue];
double longitud = [[[categorias objectAtIndex:i] objectForKey:@"longitud"]doubleValue];
CLLocationCoordinate2D lugar;
lugar.latitude = latitud;
lugar.longitude = longitud;
NSString *nombre = [[categorias objectAtIndex:i] objectForKey:@"titulo"];
NSString *direccion = [[categorias objectAtIndex:i] objectForKey:@"direccion"];
CLLocationCoordinate2D coordinate3;
coordinate3.latitude = latitud;
coordinate3.longitude = longitud;
myAnnotation *annotation3 = [[myAnnotation alloc] initWithCoordinate:coordinate3 title:nombre];
[self.mapView addAnnotation:annotation3];
}
}
}
}
And this is my code for the viewForAnnotation method:
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id)annotation {
if([annotation isKindOfClass:[MKUserLocation class]])
return nil;
static NSString *identifier = @"myAnnotation";
MKPinAnnotationView * annotationView = (MKPinAnnotationView*)[self.mapView dequeueReusableAnnotationViewWithIdentifier:identifier];
if (!annotationView)
{
annotationView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:identifier];
annotationView.pinColor = MKPinAnnotationColorPurple;
annotationView.animatesDrop = YES;
annotationView.canShowCallout = YES;
}else {
annotationView.annotation = annotation;
}
annotationView.rightCalloutAccessoryView = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
return annotationView;
}
My first question is: how to update the viewForAnnotation method to detect the group of the selected annotation to change the pin colour.
Since you're only showing one group (one color) of annotations at a time, the simplest, most direct (but crude -- not recommended) approach is:
In
viewForAnnotation
, setpinColor
based on the current value ofmiControl.selectedSegmentIndex
.This will only work right if you show one group of annotations at a time and it ties the value of the segmented control (some external UI element) with the map delegate method. In the future, you may want to show multiple groups at once or you may want to change the UI that controls what groups are shown and now you have to change the code in
viewForAnnotation
, etc.Notice that in the
viewForAnnotation
delegate method, it passes a reference to the annotation object that the map wants the view for (theannotation
parameter).If the annotation object itself knew what group it belonged to, then you could set the
pinColor
inviewForAnnotation
based on some property ofannotation
.So the recommended approach is to add the data needed to the annotation object itself (to your
myAnnotation
class). You could add agrupo
property to it, set this property when you create each annotation, then check it inviewForAnnotation
to set thepinColor
. For example:In myAnnotation.h:
In the
changeOpcion:
method where you add an annotation:Finally, in
viewForAnnotation
, right before returning the view, set thepinColor
based ongrupo
:This way, you could show multiple or all groups (colors) at once and the
viewForAnnotation
doesn't rely on the external UI.Just a comment on the code unrelated to your question or problem:
In the
changeOpcion:
method, there is unnecessary duplication of code where it loops through the annotations. The only difference between the three blocks is the value ofgrupo
that it is checking (if (grupo == 1)
,if (grupo == 2)
,if (grupo == 3)
).One alternative is to create a method that has
grupo
as a parameter and then call that method fromchangeOpcion:
. Example: