Reputation: 1694
I have a custom MKAnnotationView
. In its setselected:animated
method I'm adding to it a custom bubble loaded from a nib, adjust the annotationview's frame to include this view and redraw the annotation circle with other color, like this (first - not selected , second - selected, blue - frame, green - custom bubble view with alpha = 0.8, red - the annotationview):
It works fine, the bubble appears, and can be "closed" only by tapping outside of it (this is why I've increased the frame). I have some buttons on this bubble and they are clickable if there is nothing under the annotation just the map.
BUT when under the callout bubble there is another annotation I can click "through" the entire bubble. When I tap on one of the buttons, the tap highlight appears, but an other annotation gets selected because the didSelectAnnotationView
fires ...
I tried to make the bubble opaque/semitransparent, no luck; set exclusiveTouch on buttons, on the view itself, no luck; tried not to mess with frame, still can click through. Am I missing something ?
Thanks
Edit : Shorter: Why can I click through a UIView
added in addSubview
in an MKAnnotationView if there is other MKAnnotaionView under this UIView ?
Details :
- (void)setSelected:(BOOL)selected animated:(BOOL)animated
{
if(selected)
{
initialFrame = self.frame; // save frame and offset to restore when deselected
initialOffset = self.centerOffset; // frame is correct for a circle, like {{2.35, 1.47}, {12, 12}}
if (!self.customCallout)
{
self.customCallout = [[[NSBundle mainBundle] loadNibNamed:@"CustomCallout" owner:self options:nil] objectAtIndex:0];
}
// adjust annotationview's frame and center
// callout is 200x120, here frame is {{2.35, 1.47}, {200, 132}}
self.customCallout.layer.cornerRadius=5;
self.customCallout.exclusiveTouch = YES;
[self addSubview:self.customCallout];
}
...
}
initWithAnnotation
has these :
self.canShowCallout = NO; // to appear the subview
self.exclusiveTouch = YES; // ...
self.enabled = YES;
self.opaque = YES;
Upvotes: 3
Views: 2388
Reputation: 1
I had this issue recently, spending way to much time that I did not have. Solving it, actually ended up being quite straightforward, of course only realizing such after spending ages.
You'll simply want to subclass your MapView, and within that subclass to the following:
override func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
debugPrint(gestureRecognizer)
if gestureRecognizer is UITapGestureRecognizer {
return true
} else {
return false
}
}
The reason being, that all the handling of map interaction, such as zooming panning etc, seems to be handled internally, and not accessible to us. The gestures causing us problems is however accessible, but for my case, I only want the tap gesture that handles selecting and deselecting of an annotation.
Upvotes: 0
Reputation: 60
I think you will find the following links very useful:
http://blog.asynchrony.com/2010/09/building-custom-map-annotation-callouts-part-2/
How do I make a MKAnnotationView touch sensitive?
The first link discusses (among other things) how to prevent the propagation and the second one how to detect the touches.
Upvotes: 0
Reputation: 3201
The default behavior of the touch handling methods (touchesBegan: touchesEnded: etc.) have this note in the documentation:
The default implementation of this method does nothing. However immediate UIKit subclasses of UIResponder, particularly UIView, forward the message up the responder chain.
MKAnnotationView is a subclass of UIVIew. As a result, when your annotation gets a touch, it is passing it to it's super class and on up the responder chain, so eventually you map view gets the touch and activates the covered annotation.
To resolve, implement the touch handling methods in your annotationView class, and do not pass the touch events up the responder chain.
Upvotes: 3
Reputation: 196
can u check which event fire first
1, the button on bubble
2, didSelectAnnotationView
if the button on bubble fire first you can intersect the touch in bubble by subclassing the
touchesBegan:touches
touchesMove:touches
touchesEnd:touches
in bubble view to preventing the propagation
Upvotes: 0