【问题标题】:Detecting selected annotation to change pin color检测选定的注释以更改引脚颜色
【发布时间】:2014-03-17 17:53:23
【问题描述】:

我现在正在研究 mapView。这是场景:

  1. 所有注释都来自 JSON 对象(MySQL 表)。
  2. 注解按源表分组:
  3. 表 1-> Ofertas,表 2-> Cursos,表 3-> Eventos。
  4. 最初会显示一个地图区域,该区域足够大,可以稍后显示所有注释。
  5. 有一个 UISegmentedControll 可让用户选择应显示的注释组。

在此应用状态下,我需要进行以下更新:

  1. 每个注释组应具有不同的引脚颜色。

这是我用来根据所选索引将注释绘制到 mapView 的方法:

- (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];


            }
        }
    }


}

这是我的 viewForAnnotation 方法的代码:

- (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;
}

我的第一个问题是:如何更新 viewForAnnotation 方法以检测所选注释的组以更改引脚颜色。

【问题讨论】:

    标签: ios mkmapview mkannotationview


    【解决方案1】:

    由于您一次只显示一组(一种颜色)注释,因此最简单、最直接(但粗略 -- 不推荐)的方法是:

    viewForAnnotation中,根据miControl.selectedSegmentIndex的当前值设置pinColor

    这只有在您一次显示一组注释并且将分段控件(一些外部 UI 元素)的值与映射委托方法联系起来时才能正常工作。将来,您可能希望一次显示多个组,或者您可能想更改控制显示哪些组的 UI,现在您必须更改 viewForAnnotation 中的代码等。


    请注意,在 viewForAnnotation 委托方法中,它传递了对地图想要查看的注释对象的引用(annotation 参数)。

    如果注释对象本身知道它属于哪个组,那么您可以根据annotation 的某些属性在viewForAnnotation 中设置pinColor

    因此推荐的方法是将所需的数据添加到注释对象本身(添加到您的myAnnotation 类)。您可以为其添加一个grupo 属性,在创建每个注释时设置此属性,然后在viewForAnnotation 中检查它以设置pinColor。例如:

    • myAnnotation.h 中:

      @property (nonatomic, assign) int grupo;
      
    • changeOpcion: 方法中添加注解:

      myAnnotation *annotation3 = [[myAnnotation alloc] initWith...
      annotation3.grupo = grupo;  // <-- tell the annotation what group it's in
      [self.mapView addAnnotation:annotation3];
      
    • 最后,在viewForAnnotation 中,在返回视图之前,根据grupo 设置pinColor

      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;
      

    这样,您可以一次显示多个或所有组(颜色),viewForAnnotation 不依赖于外部 UI。



    只是对与您的问题或问题无关的代码发表评论:
    changeOpcion: 方法中,在循环注解的地方存在不必要的代码重复。这三个块之间的唯一区别是它正在检查的grupo 的值(if (grupo == 1)if (grupo == 2)if (grupo == 3))。

    另一种方法是创建一个以grupo 作为参数 的方法,然后从changeOpcion: 调用该方法。示例:

    - (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;
        }
    }
    

    【讨论】:

    • 谢谢,您的回答非常清楚易懂。我从你身上学到了很多。祝你一切顺利。非常非常感谢你。这正是我所需要的。
    • 我已经实现了你的答案,但是有一个我不明白的行为。我将打开一个新问题来解释它...
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-03
    • 1970-01-01
    • 2011-10-22
    • 2023-03-21
    • 2012-01-05
    相关资源
    最近更新 更多