有一个bug in MapKit that can cause duplicate callout views on an annotation。如果时间恰到好处,则注释视图可以在被选中时重复使用,并且显然恰好在实际添加了标注视图之前。结果,旧的标注视图卡在那里,新的标注将出现在它的顶部或旁边。以下是OS X应用程序中的内容:
此地图上只有一个注释。如果单击地图上的其他位置以取消选择注释,则只有一个标注消失。在某些情况下,您可能会有两个具有完全不同信息的标注,这对于使用您的应用的人来说会让您感到困惑。
这是我放在一起的示例OS X项目的大部分内容,它说明了这个错误:
@import MapKit;
#import "AppDelegate.h"
#import "JUNMapAnnotation.h"
@interface AppDelegate () <MKMapViewDelegate>
@property (weak) IBOutlet NSWindow *window;
@property (weak) IBOutlet MKMapView *mapView;
@property BOOL firstPin;
- (void)placeAndSelectPin;
- (JUNMapAnnotation *)placePin;
- (void)clearPins;
@end
@implementation AppDelegate
- (IBAction)dropSomePins:(id)sender {
self.firstPin = YES;
[self placeAndSelectPin];
[self performSelector:@selector(placeAndSelectPin) withObject:nil afterDelay:0.0001];
}
#pragma mark - Private methods
- (void)placeAndSelectPin {
[self clearPins];
JUNMapAnnotation *annotation = [self placePin];
[self.mapView deselectAnnotation:annotation animated:NO];
[self.mapView selectAnnotation:annotation animated:YES];
}
- (JUNMapAnnotation *)placePin {
CLLocationCoordinate2D coord = CLLocationCoordinate2DMake(50.0,50.0);
JUNMapAnnotation *annotation = [[JUNMapAnnotation alloc] initWithCoordinate:coord];
annotation.title = @"Annotation";
annotation.subtitle = (self.firstPin) ? @"This is an annotation with a longer subtitle" : @"This is an annotation";
[self.mapView addAnnotation:annotation];
self.firstPin = NO;
return annotation;
}
- (void)clearPins {
[self.mapView removeAnnotations:self.mapView.annotations];
}
#pragma mark - MKMapViewDelegate
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation {
if ([annotation isKindOfClass:[JUNMapAnnotation class]]) {
static NSString *identifier = @"annotationView";
MKPinAnnotationView *view = (MKPinAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:identifier];
if (view == nil) {
view = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:identifier];
view.canShowCallout = YES;
NSLog(@"new annotation view");
} else {
view.annotation = annotation;
}
return view;
}
return nil;
}
@end
iOS中似乎存在同样的错误,但我在那里重新创建它的时间更为艰难。
虽然我在等苹果公司解决这个问题,但我希望尽可能地解决这个问题。到目前为止,我已经提出了一些可能性:
mapView:viewForAnnotation:
中重复使用注释视图时,请删除其所有子视图。目前似乎标注是唯一的子视图,尽管它似乎并不是一个特别安全的黑客。它也只是一些作品 - 它不会阻止重复的标注出现,它只是让它们永远不会粘在一起。 (当这个bug第一次发生时,实际上还没有任何子视图。)dequeueReusableAnnotationViewWithIdentifier:
返回包含任何子视图的视图,请忽略它并创建一个新视图。这似乎比2更安全,并且几乎没有1那么低效。但与2一样,它不是一个完整的解决方法。我也尝试在我能想到的每个地方添加deselectAnnotation:animated:
,但我找不到任何可行的地方。我假设一旦重复使用注释视图,MapView就会丢失第一个标注的跟踪,因此它的常规方法都不会消除它。
答案 0 :(得分:1)
这有点偏离了场,但是......
尝试使用2个不同的重用标识符注册相同的单元类。在viewForAnnotation:
中,在出列单元格时使用每个标识符之间交替。这应该可以防止连续两次从同一队列中获取。