mapView:didDeselectAnnotationView: delegate method getting called before the annotation view is actually deselected
I am working with a map view populated with custom pins. When the user taps somewhere on the map to deselect a pin, I want to implement the map such that the pin does not become deselected (i.e. users are not able to deselect pins without selecting other pins, so at least one pin will always be selected). Here is my implementation of the didDeselectAnnotationView method:
-(void)mapView:(MKMapView *)mapView didDeselectAnnotationView:(MKAnnotationView *)view
{
[mapView selectAnnotation:view.annotation animated:NO];
}
Essentially, I'm trying to reselect the annotation. However, after some debugging and printing to console, I realized that the annotation view isn't actually being deselected until after the method didDesele开发者_C百科ctAnnotationView: finishes running (that is, the order of events goes: user taps somewhere on map, didDeselectAnnotationView: is called and finishes executing, the annotation view is actually deselected). Has anyone else experienced this problem, or does anyone know another way to enforce the behavior for the map such that users are unable to deselect pins without selecting other pins, so that one pin will always be selected?
Thanks for the help.
Try deferring the re-select until after didDeselectAnnotationView
is finished:
-(void)mapView:(MKMapView *)mapView didDeselectAnnotationView:(MKAnnotationView *)view
{
[self performSelector:@selector(reSelectAnnotationIfNoneSelected:)
withObject:view.annotation afterDelay:0];
}
- (void)reSelectAnnotationIfNoneSelected:(id<MKAnnotation>)annotation
{
if (mapView.selectedAnnotations.count == 0)
[mapView selectAnnotation:annotation animated:NO];
}
EDIT: Keep in mind that this method prevents any other pins from being selected, which was unknown when this answer was created. Chances are, this is not your desired behaviour.
I know this is an old question, but the accepted answer didn't work for me in iOS 8. What worked for me was completely disabling the UITapGestureRecognizer that, by default, is included in a MKMapView.
- (void)disableTapRecognizerForMapView:(MKMapView *)mapView {
NSArray *a = [[self.mapView.subviews objectAtIndex:0] gestureRecognizers];
for (id gesture in a)
if ([gesture isKindOfClass:[UITapGestureRecognizer class]])
[gesture setEnabled:NO];
}
Hopefully this helps someone else.
Cheers!
I had a similar issue, but the other way around.
Depending on the pin selected a table would scroll to the respective cell. If no pin was selected the table would scroll back to the first cell. The deselect method was being called at the same time the select method was being called when another pin was selected and the table would not scroll as required.
The following code resolved the issue and is a slight modification to Anna's solution.
- (void)mapView:(MKMapView *)mapView didDeselectAnnotationView:(MKPinAnnotationView *)view
{
if ([view.annotation isKindOfClass:[MKUserLocation class]])
return;
[self performSelector:@selector(resetTableScroll:)
withObject:view.annotation afterDelay:.5];
}
- (void)resetTableScroll:(id<MKAnnotation>)annotation{
if (theMap.selectedAnnotations.count == 0)
{
NSIndexPath *position = [NSIndexPath indexPathForRow:0 inSection:0];
[[self theTable] scrollToRowAtIndexPath:position atScrollPosition:UITableViewScrollPositionMiddle animated:YES];
}}
Awesome answer from Anna. Here the answer in Swift 3 or 4 :D
func mapView(_ mapView: MKMapView, didDeselect view: MKAnnotationView) {
perform(#selector(MyViewController.reSelectAnnotationIfNoneSelected(_:)), with: view.annotation, afterDelay: 0)
}
func reSelectAnnotationIfNoneSelected(_ annotation: MKAnnotation) {
if mapView.selectedAnnotations.count == 0 {
mapView.selectAnnotation(annotation, animated: false)
}
}
if you add a gesture for map view, try this:
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer;
return NO, it works
精彩评论