在XCode 4.6中滚动地图时,MapKit会更改注释视图顺序

在XCode 4.6中滚动地图时,MapKit会更改注释视图顺序,xcode,mapkit,mkannotationview,Xcode,Mapkit,Mkannotationview,我是一名经验丰富的iOS开发人员,但这确实让我感到困惑。我同时向苹果提交了一份问题报告 我正在向MKMapKit映射(Xcode 4.6)添加注释。每个注释都是一个MyAnnotation类;MyAnnotation定义了一个属性location\u id,我用来跟踪该注释 问题很简单:我希望位置id为-1的MyAnnotation出现在所有其他内容之前 为此,我将覆盖MKMapViewDelegate中的mapView:didAddAnnotationViews: -(void)mapView

我是一名经验丰富的iOS开发人员,但这确实让我感到困惑。我同时向苹果提交了一份问题报告

我正在向MKMapKit映射(Xcode 4.6)添加注释。每个注释都是一个MyAnnotation类;MyAnnotation定义了一个属性location\u id,我用来跟踪该注释

问题很简单:我希望位置id为-1的MyAnnotation出现在所有其他内容之前

为此,我将覆盖MKMapViewDelegate中的mapView:didAddAnnotationViews:

-(void)mapView:(MKMapView *)mapView didAddAnnotationViews:(NSArray *)views {


// Loop through any newly added views, arranging them (z-index)
for (MKAnnotationView* view in views) {

    // Check the location ID
    if([view.annotation isKindOfClass:[MyAnnotation class]] && [((MyAnnotation*)(view.annotation)).location_id intValue]==-1 ) {

        // -1: Bring to front
        [[view superview] bringSubviewToFront:view];
        NSLog(@"to FRONT: %@",((MyAnnotation*)view.annotation).location_id);

    } else {

        // Something else: send to back
        [[view superview] sendSubviewToBack:view];
        NSLog(@"to BACK: %@",((MyAnnotation*)view.annotation).location_id);
    }
}
}
这个很好用。我有一个“添加”按钮,可以在地图中心附近的随机位置添加注释。每次我按下“添加”按钮,就会出现一个新的注释;但是没有任何内容隐藏位置为-1的注释

**直到**我滚动

一旦我开始滚动,我所有的注释都被重新排列(z顺序),我仔细的堆叠不再适用

真正令人困惑的是,我以前做过图标顺序堆叠,没有任何问题。我创建了一个全新的单视图应用程序来测试这个问题;将MKAnnotationView项目发送到后面或前面仅在滚动之前有效。除了上面描述的代码外,此框架应用程序中没有其他内容。我想知道最新的MapKit框架中是否存在某种缺陷

最初的问题是在用户滚动时尝试添加新注释(mapView:regionDidChangeAnimated:)。注释增加了;地图视图:didaddAnnotationView:代码激发;然后,框架中的一只看不见的手(大概是在卷轴完成时)扰乱了顺序

如果您感兴趣,以下是我的说明:

-(MKAnnotationView*)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation {


// Is this an A91Location?
if([annotation isKindOfClass:[MyAnnotation class]]){

    MyAnnotation* ann=(MyAnnotation*)annotation;

    NSLog(@"viewForAnnotation with A91Location ID %@",ann.location_id);


    if([ann.location_id intValue]==-1){

        // If the ID is -1, use a green pin
        MKPinAnnotationView* green_pin=[[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:nil];
        green_pin.pinColor=MKPinAnnotationColorGreen;
        green_pin.enabled=NO;
        return green_pin;

    } else {

        // Otherwise, use a default (red) pin
        MKPinAnnotationView* red_pin=[[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:nil];
        red_pin.enabled=NO;
        return red_pin;
    }
}


// Everything else
return nil;


}
-(MKAnnotationView*)地图视图:(MKMapView*)地图视图注释:(id)注释{
//这是A91位置吗?
if([annotation isKindOfClass:[MyAnnotation class]]){
MyAnnotation*ann=(MyAnnotation*)注释;
NSLog(@“查看带有91个位置ID的注释%@”,ann.location\u ID);
如果([ann.location\u id intValue]==-1){
//如果ID为-1,请使用绿色pin
MKPinAnnotationView*绿色_pin=[[MKPinAnnotationView alloc]initWithAnnotation:annotation重用标识符:nil];
绿色_pin.pinColor=MKPinAnnotationColorGreen;
绿色引脚已启用=否;
返回绿色_引脚;
}否则{
//否则,请使用默认(红色)pin
MKPinAnnotationView*red_pin=[[MKPinAnnotationView alloc]initWithAnnotation:annotation重用标识符:nil];
红色引脚已启用=否;
返回红色_针;
}
}
//其他一切
返回零;
}
我的班级:

@interface MyAnnotation : NSObject <MKAnnotation>

@property (strong, nonatomic, readonly) NSNumber* location_id;
@property (strong, nonatomic, readonly) NSString*  name;
@property (strong, nonatomic, readonly) NSString*  description;
@property (nonatomic) CLLocationCoordinate2D coordinate;

-(id) initWithID:(NSNumber*)location_id name: (NSString*) name description:(NSString*) description location:(CLLocationCoordinate2D) location;

// For MKAnnotation protocol... return name and description, respectively
-(NSString*)title;
-(NSString*)subtitle;

@end
@接口MyAnnotation:NSObject
@属性(强、非原子、只读)NSNumber*location\u id;
@属性(强、非原子、只读)NSString*名称;
@属性(强、非原子、只读)NSString*说明;
@性质(非原子)CLLocationCoordinate2D坐标;
-(id)initWithID:(NSNumber*)位置\ id名称:(NSString*)名称描述:(NSString*)描述位置:(CLLocationCoordinate2D)位置;
//对于MKAnnotation协议。。。分别返回名称和描述
-(NSString*)标题;
-(NSString*)副标题;
@结束

您是否可以尝试以下解决方法:

1) 删除mapView:DidAddAnnotationView中的代码:

“P>2”当地图移动或捏(我认为这是你认为是一个卷轴右)-我这样做的手势,而不是MavVIEW区域改变,因为我有坏的经验,如无法解释的行为与后者。
//recognise the paning gesture to fire the didDragMap method
UIPanGestureRecognizer* panRec = [[UIPanGestureRecognizer alloc] initWithTarget:self     action:@selector(didDragMap:)];
[panRec setDelegate:self];
[self.mapView addGestureRecognizer:panRec];

//recognise the pinching gesture to fire the didPinchMap method
UIPinchGestureRecognizer *pinchRec = [[UIPinchGestureRecognizer alloc]initWithTarget:self action:@selector(didPinchMap:)];
[pinchRec setDelegate:self];
//[pinchRec setDelaysTouchesBegan:YES];
[self.mapView addGestureRecognizer:pinchRec];

//recognise the doubleTap
UITapGestureRecognizer *doubleTapRec = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(didPinchMap:)];
[doubleTapRec setDelegate:self];
doubleTapRec.numberOfTapsRequired = 2;
[self.mapView addGestureRecognizer:doubleTapRec];
3) 编写自定义“plotAnnotations”函数以显示注释。此函数将遍历所有注释,并将它们保存在按位置id DESC排序的数组“annotationsToShow”中,以便最后添加位置id-1。使用[self.mapView addAnnotations:annotationsToShow];来展示它们

4) 在手势识别器函数中调用plotAnnotations

- (void)didDragMap:(UIGestureRecognizer*)gestureRecognizer {
    if (gestureRecognizer.state == UIGestureRecognizerStateEnded){
        [self plotAnnotations];
    }
}

- (void)didPinchMap:(UIGestureRecognizer*)gestureRecognizer {
    if (gestureRecognizer.state == UIGestureRecognizerStateEnded){
        [self plotAnnotations];
    }
}

5) 在3中显示新注释之前,您可能需要删除所有注释。[self.mapView removeAnnotations:annotationsToRemove]

看来我不是唯一一个经历过这种情况的人:投票表决一个记录完整的问题。事实上,对于这个问题,似乎只有一些骇人的解决办法,而且苹果没有提供任何官方API来管理MKAnnotationViews的z顺序!