I’m trying to remove a pin from a map. I have an observer on the @”selected” property of the MKPinAnnotationView so I know which object to delete. When the user taps the trash can icon and a pin is selected, this method gets called:
- (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];
}
This method works fine if I do not drag the pin anywhere. If I drag the pin, my pinView in the above method returns nil, and the MKPinAnnotationView never gets removed from the MKMapView. I’m not sure why. Here’s the didChangeDragState delegate method:
- (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;
}
}];
}
}
In both the didChangeDragState: and deleteAnnotationView: methods, my self.address object has a valid address. For some reason though, when the pin is dragged, the pinView is nil. Any thoughts? Thanks!
Observing an annotation view’s
selectedproperty via KVO should be unnecessary since there’s thedidSelectAnnotationViewdelegate method and (even better in your case) theselectedAnnotationsproperty inMKMapView.Assuming the user taps the trash can after selecting a pin, the trash can tap method can get the currently selected annotation through the
selectedAnnotationsproperty. For example:In the above example, there was no need to access the annotation’s view, no observer and no need for your own “currentAddress” property.
If instead you want to do some action immediately when an annotation is selected, you can put the code in the
didSelectAnnotationViewdelegate method. There, the annotation selected isview.annotation.Regarding the issue on the drag-end, the current code is completely replacing the view’s
annotation. I think this is only a good idea when the view is being created or re-used in theviewForAnnotationdelegate method. In the drag-end method, you should instead try updating theview.annotation‘s properties instead of replacing with an entirely new object.