Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Issue with overlapping annotations (MKAnnotationView) on map

In my iphone application, I'm using MapKit with MKMapView and custom MKAnnotationView.

The problem is when annotations overlap on map (in my app, annotations are photos and those photos may overlap) and when you tap on the annotation that appears on front, it's another annotation (on back) which receives the event (seems to be random).

I didn't find any way to send the event to the front annotation. I cannot believe this bug/problem doesn't have any solution!

Z ordering and Order of overlapping annotations questions on stackoverflow did not help me that much.

Please any idea is welcome (even dirty solutions)!

Here's some of my code (nothing fancy, very common):

CustomAnnotation.h

@interface CustomAnnotation : NSObject <MKAnnotation> {
   @private
   CustomAnnotationView* view;
}

    @property (nonatomic, retain) CustomAnnotationView* view;

@end

CustomAnnotation.m

@implementation CustomAnnotation

@synthetize view;

CustomAnnotationView.h

@interface CustomAnnotationView : MKAnnotationView {
}

@end

CustomAnnotationView.m

@implementation CustomAnnotationView

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{
// Do something related to the annotation tapped
}

@end

Main class ... // Annotations are added and some of them overlaps with others.

- (void)addAnnotation:(CustomAnnotation*)annotation {
    [map addAnnotation:annotation];
}

...

- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation {

    NSString* identifier = getIdentifierFromAnnotation(annotation);
    CustomAnnotationView* view;
    if(!(view = (CustomAnnotationView*)[map dequeueReusableAnnotationViewWithIdentifier:identifier])) {
        view = [[CustomAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier: identifier];
        [(CustomAnnotation*)annotation setView:view];
        [view release];
    }
    return view;
}
like image 680
Alexandre Gellibert Avatar asked Mar 18 '10 15:03

Alexandre Gellibert


1 Answers

Finally, the best way I found and that avoids loosing map funcionalities is to:

  • let the touch listener on CustomAnnotationView (touchesEnded) (on each annotation)

  • when receiving touch event, transfer the event to main class

  • main class loops on annotations and keeps the annotation that has a good location (touch event in the annotation frame) and that is in front

It works pretty well.

like image 149
Alexandre Gellibert Avatar answered Oct 15 '22 13:10

Alexandre Gellibert