将地图中的注释添加到NSMutableArray中

时间:2014-03-03 19:00:36

标签: ios nsmutablearray mkmapview mkannotation

我有一张地图,我可以使用可自定义的字幕添加多个注释。我想将注释放入带有更新字幕的数组中。

目前,当我添加注释时,它会进入数组,但我不知道如何使用副标题更新数组,如果从地图中删除注释,则从数组中删除注释。

我还想在切换到下一个视图时将所有注释添加到数组中,但不知道如何做到这一点。

我目前的代码:

使用UIGestureRecognizer添加注释

    MapAnnotation *mapPoint = [[MapAnnotation alloc]init];

    mapPoint.coordinate = touchMapCoordinate;
    mapPoint.title = address;
    mapPoint.subtitle = @"";

    [self.map addAnnotation:mapPoint];

    self.mapLatitudeString = [NSString stringWithFormat:@"%f",mapPoint.coordinate.latitude];
    self.mapLongitudeString = [NSString stringWithFormat:@"%f",mapPoint.coordinate.longitude];
    self.mapTitleString = [NSString stringWithFormat:@"%@", mapPoint.title];
    self.mapSubtitleString = [NSString stringWithFormat:@"%@", mapPoint.subtitle];

    self.mapAnnotation = [NSString stringWithFormat:@"%d,%@,%@,%@,%@",self.mapAnnotationArray.count, self.mapLatitudeString, self.mapLongitudeString, self.mapTitleString, self.mapSubtitleString];

    if (!self.mapAnnotationArray) {
        self.mapAnnotationArray = [[NSMutableArray alloc] init];
    }
    [self.mapAnnotationArray addObject:self.mapAnnotation];
    NSLog(@"%@", self.mapAnnotationArray);

编辑字幕并从警报视图中删除注释

- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex{
    if (buttonIndex == 0) {
    }
    if (buttonIndex == 1) {
        if (self.map.selectedAnnotations.count > 0)
        {
            id<MKAnnotation> ann = [self.map.selectedAnnotations objectAtIndex:0];

            if ([ann isKindOfClass:[MapAnnotation class]])
            {
                MKPointAnnotation *pa = (MKPointAnnotation *)ann;
                pa.subtitle = [[alertView textFieldAtIndex:0] text];
            }
        }
    }
    if (buttonIndex == 2) {
        [self.map removeAnnotations:self.map.selectedAnnotations];
    }
}

1 个答案:

答案 0 :(得分:1)

使用当前的方法将每个注释的格式化字符串表示(包括序列号)添加到mapAnnotationArray,维护数组的过程很繁琐:

  1. 要更新其中一个格式化字符串中的字段,您必须:
    一个。循环通过阵列,
    湾解析字符串(例如,使用componentsSeparatedByString),
    C。检查字段是否与您要查找的注释匹配,
    d。使用新值重建格式化字符串,
    即使用replaceObjectAtIndex:withObject:
  2. 更新数组中的字符串
  3. 要从数组中删除条目,您必须:
    一个。执行与1a到1c相同的步骤,
    湾使用removeObjectAtIndex:执行删除字符串 C。更新所有剩余注释中的注释序列号
  4. 每次要在mapAnnotationArray中检索或搜索字段时,都必须执行这些步骤。它不高效或灵活(如果用户决定在副标题中使用逗号,如果地址包含逗号,等等)。


    相反,将注释对象本身存储在mapAnnotationArray中,并且只在需要将数据提交到服务器时生成格式化的字符串表示。在数组中存储适当的对象可以让您利用面向对象的方法。

    1. 在将注释添加到地图的方法中,不是将格式化的字符串添加到mapAnnotationArray,而是添加注释本身:

      [self.mapAnnotationArray addObject:mapPoint];
      
    2. 如果您在警报视图委托方法中更新注释的subtitle,那么现在不需要对mapAnnotationArray执行任何操作,因为注释对象在数组是您更新subtitle 完全 相同的对象。您可以在此处NSLog数组以查看更改。

    3. 如果在警报视图委托方法中删除注释,则需要从mapAnnotationArray中删除相同的对象(地图视图不知道您的数组):

      if (buttonIndex == 2) 
      {
          if (self.map.selectedAnnotations.count > 0)
          {
              id<MKAnnotation> ann = [self.map.selectedAnnotations objectAtIndex:0];
              if ([ann isKindOfClass:[MapAnnotation class]])
              {
                  [self.mapAnnotationArray removeObject:ann];
              }
              [self.map removeAnnotations:self.map.selectedAnnotations];
          }
      }
      
    4. 接下来,为了更容易生成格式化字符串并调试mapAnnotationArray的内容,请将description方法的辅助方法和覆盖添加到MapAnnotation } class:

      -(NSString *)stringForServer
      //You can name this method whatever you want.
      //Builds the comma-delimited representation 
      //of this annotation (excluding the sequence number).
      //Note this format still "breaks" if title or subtitle contain commas.
      {
          NSString *result = [NSString stringWithFormat:@"%f,%f,%@,%@",
                              self.coordinate.latitude, 
                              self.coordinate.longitude, 
                              self.title, 
                              self.subtitle];
          return result;
      }
      
      -(NSString *)description
      //This method must be named this.
      //When you NSLog this object, it will call this method to get
      //what string to display for it.
      {
          return [NSString stringWithFormat:@"%@ (%@)", 
                     [super description], [self stringForServer]];
      }
      
    5. 最后,无论您将数据提交到服务器,都要遍历数组并从注释对象生成格式化的字符串(并在序列号前加上前缀)。此示例仅循环遍历数组,NSLog为每个注释的格式化字符串:

      for (int i=0; i < self.mapAnnotationArray.count; i++)
      {
          MapAnnotation *ma = (MapAnnotation *)[self.mapAnnotationArray objectAtIndex:i];
          NSString *maString = [ma stringForServer];
          NSString *fullStringForServer = [NSString stringWithFormat:@"%d,%@", i, maString];
          NSLog(@"maa[%d] = %@", i, fullStringForServer);
      }
      

      当您准备好保存数据时,前缀序列号可避免重新编号和重复问题。当然,这假设注释不必在保存期间保持相同的序列号。

      另请考虑使用JSON而不是逗号分隔格式。 NSJSONSerialization使相对容易。有关示例,请参阅Convert an iOS objective c object to a JSON string