MKMapView注释更改/丢失顺序?

Set*_*son 6 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;
}
Run Code Online (Sandbox Code Playgroud)

小智 7

当您调用addAnnotation或时addAnnotations,地图视图会将引用添加到其内部注释列表中.

简单地返回这个内部列表(它可能是什么类型)的annotations属性.MKMapViewNSArray

我不知道文档中的任何位置,它声明该annotations属性以与添加注释相同的顺序返回数组.如果已showsUserLocation打开,即使您没有明确指定,该数组也将包含该注释添加它.

您不需要关心也不应该依赖于annotations属性中对象的顺序.

关于代码的一些建议:

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