Overlapping annotations and touch propagation
When annotations overlap, the touch events on the top most annotation gets sent to the underlying annotations so it is sometimes impossible to select an annotation to expand and shrink or even use the disclosure button without triggering the annotation(s) underneath.
Have you encountered this?

Code to reproduce
- (NSArray *)annotations {
// Empire State Building
JPSThumbnail *empire = [[JPSThumbnail alloc] init];
empire.image = [UIImage imageNamed:@"empire.jpg"];
empire.title = @"Empire State Building";
empire.subtitle = @"NYC Landmark";
empire.coordinate = CLLocationCoordinate2DMake(40.75f, -73.99f);
empire.disclosureBlock = ^{ NSLog(@"selected Empire"); };
// Apple HQ
JPSThumbnail *apple = [[JPSThumbnail alloc] init];
apple.image = [UIImage imageNamed:@"apple.jpg"];
apple.title = @"Apple HQ 1";
apple.subtitle = @"Apple Headquarters 1";
apple.coordinate = CLLocationCoordinate2DMake(37.33f, -122.03f);
apple.disclosureBlock = ^{ NSLog(@"selected Appple"); };
JPSThumbnail *apple2 = [[JPSThumbnail alloc] init];
apple2.image = [UIImage imageNamed:@"apple.jpg"];
apple2.title = @"Apple HQ 2";
apple2.subtitle = @"Apple Headquarters 2";
apple2.coordinate = CLLocationCoordinate2DMake(37.34f, -123.03f);
apple2.disclosureBlock = ^{ NSLog(@"selected Appple 2"); };
JPSThumbnail *apple3 = [[JPSThumbnail alloc] init];
apple3.image = [UIImage imageNamed:@"apple.jpg"];
apple3.title = @"Apple HQ 3";
apple3.subtitle = @"Apple Headquarters 3";
apple3.coordinate = CLLocationCoordinate2DMake(37.35f, -113.03f);
apple3.disclosureBlock = ^{ NSLog(@"selected Appple 3"); };
// Parliament of Canada
JPSThumbnail *ottawa = [[JPSThumbnail alloc] init];
ottawa.image = [UIImage imageNamed:@"ottawa.jpg"];
ottawa.title = @"Parliament of Canada";
ottawa.subtitle = @"Oh Canada!";
ottawa.coordinate = CLLocationCoordinate2DMake(45.43f, -75.70f);
ottawa.disclosureBlock = ^{ NSLog(@"selected Ottawa"); };
return @[[JPSThumbnailAnnotation annotationWithThumbnail:empire],
[JPSThumbnailAnnotation annotationWithThumbnail:apple],
[JPSThumbnailAnnotation annotationWithThumbnail:apple2],
[JPSThumbnailAnnotation annotationWithThumbnail:apple3],
[JPSThumbnailAnnotation annotationWithThumbnail:ottawa]];
}
Thanks for bringing this to my attention. Can you think of a possible solution?
Seems like didSelectAnnotationViewInMap: is called regardless of whether or not there's another annotation overlapping.
I think the touch events are propagated all the way down to the MKMapview surface and the last annotation before the surface handles the event.
I tested with 3 annotations overlapping in the order:
Top => Apple HQ 1
Middle => Apple HQ 2
Bottom => Apple HQ 3
Touching on a point that is contained by all three annotations, the touch propagates all the way down.
All this seems to happen before didSelectAnnotationViewInMap: is called so it only gets hit once.
My initial thoughts were
- Disable interaction on other annotations when one is expanded...might be too limiting as you'll have to toggle/untoggle each annotation.
- Use
hitTeston the annotationView to determine the selected one and only handle events for that view...but I can't figure out how to stop the event bubbling.
What do you think?
I agree with your first point being too limiting. I've experimented with using a custom UITapGestureController to bypass didSelectAnnotationViewInMap: but it was wonky. Even with keeping a mapView property on the annotation to center on tap, there are still weird things happening to state. Sorry I can't be more descriptive, but give it a shot and you'll see.
Hi, (perhaps too late) increasing the size of the button may solve this issue (check my fork #28)