MKMapView viewForAnnotation: returning nil



我正试图从映射中移除一个pin。我在MKPinAnnotationView的@"selected"属性上有一个观察者,所以我知道要删除哪个对象。当用户点击垃圾桶图标并选择一个pin时,该方法被称为:

- (IBAction)deleteAnnotationView:(id)sender {
MKPinAnnotationView *pinView = (MKPinAnnotationView *)[self.mapView viewForAnnotation:self.currentAddress];
[pinView removeObserver:self forKeyPath:@"selected"];
[self.mapView removeAnnotation:self.currentAddress];
[self.map removeLocationsObject:self.currentAddress];
}

如果我不把大头针拖到任何地方,这个方法都可以很好地工作。如果我拖动pin,我在上面方法中的pinView将返回nil,并且MKPinAnnotationView永远不会从MKMapView中删除。我不知道为什么。以下是didChangeDragState委托方法:

- (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view didChangeDragState:(MKAnnotationViewDragState)newState fromOldState:(MKAnnotationViewDragState)oldState {
if (newState == MKAnnotationViewDragStateEnding) {
CLLocationCoordinate2D draggedCoordinate = view.annotation.coordinate;
CLGeocoder *geocoder = [[CLGeocoder alloc] init];
CLLocation *location = [[CLLocation alloc] initWithLatitude:draggedCoordinate.latitude longitude:draggedCoordinate.longitude];
[geocoder reverseGeocodeLocation:location completionHandler:^(NSArray *placemarks, NSError *error) {
// Check for returned placemarks
if (placemarks && [placemarks count] > 0) {
CLPlacemark *topResult = [placemarks objectAtIndex:0];
AddressAnnotation *anAddress = [AddressAnnotation annotationWithPlacemark:topResult inContext:self.managedObjectContext];
view.annotation = anAddress;
self.currentAddress = anAddress;
}
}];
}
}

在didChangeDragState:和deleteAnnotationView:方法中,我的self.address对象都有一个有效的地址。但由于某种原因,当拖动接点时,接点视图为零。有什么想法吗?谢谢

通过KVO观察注释视图的selected属性应该是不必要的,因为MKMapView中有didSelectAnnotationView委托方法和selectedAnnotations属性(在您的情况下更好)。

假设用户在选择引脚后点击垃圾桶,垃圾桶点击方法可以通过selectedAnnotations属性获得当前选择的注释。例如:

if (mapView.selectedAnnotations.count == 0)
{
//No annotation currently selected
}
else
{
//The currently selected annotation is the first object in the array...
id<MKAnnotation> ann = [mapView.selectedAnnotations objectAtIndex:0];
//do something with ann...
}

在上面的例子中,不需要访问注释的视图,不需要观察者,也不需要您自己的"currentAddress"属性。

如果您希望在选择注释时立即执行某些操作,则可以将代码放入didSelectAnnotationView委托方法中。在那里,选择的注释是view.annotation


关于拖动端的问题,当前代码完全替换了视图的annotation。我认为只有在viewForAnnotation委托方法中创建或重新使用视图时,这才是一个好主意。在drag-end方法中,您应该尝试更新view.annotation的属性,而不是用一个全新的对象替换。

最新更新