Search code examples
iosannotationsmapkitmkpinannotationview

Pin colors not showed as expected as a regular basis


Following the first part of the answer to my question Detecting selected annotation to change pin color, I have updated my code as follows:

- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id)annotation {
    //7
    if([annotation isKindOfClass:[MKUserLocation class]])
        return nil;

    //8
    static NSString *identifier = @"myAnnotation";
    MKPinAnnotationView * annotationView = (MKPinAnnotationView*)[self.mapView dequeueReusableAnnotationViewWithIdentifier:identifier];
    if (!annotationView)
    {
        //9
        annotationView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:identifier];
        {
            myAnnotation *myAnn = (myAnnotation *)annotation;
            NSLog(@"ANNOTATION GRUPO = %d",myAnn.grupo);
            switch (myAnn.grupo)
            {
                case 1:
                    annotationView.pinColor = MKPinAnnotationColorRed;
                    break;
                case 2:
                    annotationView.pinColor = MKPinAnnotationColorGreen;
                    break;
                case 3:
                    annotationView.pinColor = MKPinAnnotationColorPurple;
                    break;
                default:
                    annotationView.pinColor = MKPinAnnotationColorPurple;
                    break;
            }
        }
        annotationView.animatesDrop = YES;
        annotationView.canShowCallout = YES;

    }else {
        annotationView.annotation = annotation;
    }
    annotationView.rightCalloutAccessoryView = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
    return annotationView;
}

And the changeOpcionmethod as follows:

- (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:@"id"];

                CLLocationCoordinate2D coordinate3;
                coordinate3.latitude = latitud;
                coordinate3.longitude = longitud;
                myAnnotation *annotation3 = [[myAnnotation alloc] initWithCoordinate:coordinate3 title:nombre subtitle:direccion];

                annotation3.grupo = 1;
                [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 subtitle:direccion];

                annotation3.grupo = 2;
                [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 subtitle:direccion];
                annotation3.grupo = 3;
                [self.mapView addAnnotation:annotation3];


            }
        }
    }


}

When the user selects option #2 (Eventos) from the segmentedIndex control, the pins are purple, as expected. Then if the user selects option #1 (Cursos), the pins are green, as expected, and if the user selects option #0 (Ofertas), the pins are red, as expected, but after that, if the user selects whatever option, all pins are red. Why ???


Solution

  • It sounds like the pin views are being re-used from previous annotations and their pinColor is not being updated when they are re-used.

    In the answer that you linked to, there is this statement:

    Finally, in viewForAnnotation, right before returning the view, set the pinColor based on grupo:

    The pinColor needs to be set whether you are creating a new view or if you are re-using a dequeued view. A dequeued view may have had its pinColor set for an annotation in a different group.

    The code shown in the question is only setting pinColor when creating a new view.

    That code needs to be moved out of that block and put right before the return annotationView; line:

    annotationView.rightCalloutAccessoryView = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
    
    //the code to set the pinColor goes HERE...
    myAnnotation *myAnn = (myAnnotation *)annotation;
    NSLog(@"ANNOTATION GRUPO = %d",myAnn.grupo);
    switch (myAnn.grupo)
    {
        case 1:
            annotationView.pinColor = MKPinAnnotationColorRed;
            break;
        case 2:
            annotationView.pinColor = MKPinAnnotationColorGreen;
            break;
        case 3:
            annotationView.pinColor = MKPinAnnotationColorPurple;
            break;
        default:
            annotationView.pinColor = MKPinAnnotationColorPurple;
            break;
    }
    
    return annotationView;