Detecting selected annotation to change pin color

前端 未结 1 778
悲&欢浪女
悲&欢浪女 2021-01-25 04:11

I am now working on a mapView. This is the scenario:

  1. All annotations are coming from JSON objects (MySQL tables).
  2. Annotations are grouped by source table:
相关标签:
1条回答
  • 2021-01-25 05:03

    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, set pinColor based on the current value of miControl.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 (the annotation parameter).

    If the annotation object itself knew what group it belonged to, then you could set the pinColor in viewForAnnotation based on some property of annotation.

    So the recommended approach is to add the data needed to the annotation object itself (to your myAnnotation class). You could add a grupo property to it, set this property when you create each annotation, then check it in viewForAnnotation to set the pinColor. For example:

    • In myAnnotation.h:

      @property (nonatomic, assign) int grupo;
      
    • In the changeOpcion: method where you add an annotation:

      myAnnotation *annotation3 = [[myAnnotation alloc] initWith...
      annotation3.grupo = grupo;  // <-- tell the annotation what group it's in
      [self.mapView addAnnotation:annotation3];
      
    • Finally, in viewForAnnotation, right before returning the view, set the pinColor based on grupo:

      if ([annotation isKindOfClass:[myAnnotation class]])
      {
          myAnnotation *myAnn = (myAnnotation *)annotation;
          switch (myAnn.grupo)
          {
              case 1:
                  annotationView.pinColor = MKPinAnnotationColorGreen;
                  break;
              case 2:
                  annotationView.pinColor = MKPinAnnotationColorPurple;
                  break;
              default:
                  annotationView.pinColor = MKPinAnnotationColorRed;
                  break;
          }
      }
      
      return annotationView;
      

    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 of grupo 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 from changeOpcion:. Example:

    - (void)addAnnotationsForGroup:(int)selectedGrupo
    {
        [self removeAllPinsButUserLocation2];
        NSLog(@"********0");
    
        for (int i=0; i < [categorias count]; i++) 
        {    
            int grupo = [[[categorias objectAtIndex:i] objectForKey:@"procedencia"] integerValue];
    
            if (grupo == selectedGrupo)
            {
                //code to create annotation here
            }
        }
    }
    
    - (IBAction)changeOpcion:(id)sender
    {
        switch (miControl.selectedSegmentIndex) 
        {
            case 0:
                [self addAnnotationsForGroup:1];
                break;
            case 1:
                [self addAnnotationsForGroup:2];
                break;
            case 2:
                [self addAnnotationsForGroup:3];
                break;
            default:
                break;
        }
    }
    
    0 讨论(0)
提交回复
热议问题