MKMapView注释更改/丢失顺序?

时间:2012-03-02 20:20:14

标签: iphone mkmapview mkannotation

我有一个带注释的地图视图,这些注释显示一个标注。单击标注的披露详细信息按钮后,它将转换为新视图。

我的MKAnnotations是一个实现<MKAnnotation>的自定义类。我们称之为MyClass类。它们存储在NSMutableArray中。在此视图的viewdidload期间,我将此数组中MyClass的每个对象添加到地图视图的注释中。使用调试器,我可以看到,一旦完成所有这些添加,[self.MapView annotations]顺序与NSMutableArray相同。

现在我在mapView中设置另一个断点:viewForAnnotation:并查看1)我的NSMutableArray和2)[self.MapView annotations]的顺序。阵列当然是以相同的顺序。但是,注释的顺序已被扰乱。

这对我来说是个大问题,因为我需要使用用户在下一个视图中选择的特定MyClass实例。 AKA,我想查看注释,找到它的索引,然后使用它来获取数组中的相同索引。

我现在意识到我可以直接保存注释(来自Android背景,这对我来说非常酷)。但是,我仍然在概念上不知道为什么订单变得混乱。有人能帮我吗?代码如下:

- (void)viewDidLoad
{


    if([fromString isEqualToString:@"FromList"])
        self.navigationItem.hidesBackButton = TRUE;
    else { 
        self.navigationItem.rightBarButtonItem = nil;
    }


    self.array = [MySingleton getArray];
    //set up map

    //declare latitude and longitude of map center
    CLLocationCoordinate2D center;
    center.latitude = 45;
    center.longitude = 45;

    //declare span of map (height and width in degrees)
    MKCoordinateSpan span;
    span.latitudeDelta = .4;
    span.longitudeDelta = .4;

    //add center and span to a region, 
    //adjust the region to fit in the mapview 
    //and assign to mapview region
    MKCoordinateRegion region;
    region.center = center;
    region.span = span;
    MapView.region = [MapView regionThatFits:region];

    for(MyClass *t in self.array){
        [MapView addAnnotation:t];
    }
    [super viewDidLoad];
}



//this is the required method implementation for MKMapView annotations
- (MKAnnotationView *) mapView:(MKMapView *)thisMapView 
             viewForAnnotation:(MyClass *)annotation
{


    static NSString *identifier = @"MyIdentifier";

    //the result of the call is being cast (MKPinAnnotationView *) to the correct
    //view class or else the compiler complains
    MKPinAnnotationView *annotationView = (MKPinAnnotationView *)[thisMapView 
                                                                  dequeueReusableAnnotationViewWithIdentifier:identifier];
    if(annotationView == nil)
    {
        annotationView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:identifier];
    }

    annotationView.pinColor = MKPinAnnotationColorGreen;

    //pin drops when it first appears
    annotationView.animatesDrop=TRUE;

    //tapping the pin produces a gray box which shows title and subtitle  
    annotationView.canShowCallout = YES;

    UIButton *infoButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
    annotationView.rightCalloutAccessoryView = infoButton;


    return annotationView;
}

2 个答案:

答案 0 :(得分:7)

当您致电addAnnotationaddAnnotations时,地图视图会将引用添加到其内部注释列表中。

annotations的{​​{1}}属性只是将此内部列表(无论它是什么类型)返回MKMapView

我不知道文档中是否有任何地方声明NSArray属性以与添加注释相同的顺序返回数组。如果您已启用annotations,即使你没有明确地添加它,该数组也将包含该注释。

您不需要担心,也不应该依赖showsUserLocation属性中对象的顺序。

关于代码的一些建议:

  • 由于您的annotations包含实现array的对象,而不是循环遍历它,您可以通过调用<MKAnnotation>(复数)一次性添加所有注释并将其传递给数组
  • addAnnotations中,您设置的所有属性都不依赖于任何特定的注释,因此您可以在viewForAnnotation块内设置它们。这样您就可以获得最大程度的重用。
  • 同样在if (av == nil)中,在viewForAnnotation之后,您应该将视图的if属性设置为当前注释。这是为了从另一个注释中重用视图。
  • 最后,在annotation中,不要认为viewForAnnotation属于annotation类型。如果您启用MyClass,则情况并非如此。将参数声明为showsUserLocation更安全,然后在必要时检查其类是什么,然后进行投射。

答案 1 :(得分:1)

@Anna,你说你不应该关注注释的顺序。在我的情况下,这不是真的。一些注释视图可能会重叠,我总是需要一个特定的注释视图位于两个重叠视图的顶部。所以命令DO对于注释是有意义的,因为我希望以与添加注释相同的顺序调用- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation

修改 and the solution is here :-)