9

I need some code which can be used outside of the mk* functions. I need to run my custom function to bring the FIRST and LAST markers in an array to the front. (so on top of all the other markers on my screen). I have tried

[self.view bringSubviewToFront:[[mapView annotations]objectAtIndex: 0]];

I have used [[mapView annotations]objectAtIndex: 0] in my code and that works, but it crashes when I try to bring this to the front. Am I accessing the wrong layer or something?

thanks for any help.

Matt Facer
  • 3,103
  • 11
  • 49
  • 91

3 Answers3

13

You're bringing the wrong things to the front. Namely, the annotations array is an array of objects that conform to the MKAnnotation protocol (so of type id<MKAnnotation>), and they are not views.

Instead, you should be getting the view for the annotations you want, and bring those to the front:

id<MKAnnotation> annotation = [[mapView annotations] objectAtIndex:0];
MKAnnotationView* annotationView = [mapView viewForAnnotation:annotation];
if (annotationView != nil) {
    [annotationView.superview bringSubviewToFront:annotationView];
}

However, you should note a couple of things:

  1. annotationView may be nil if the annotation is on a point that's off screen, or if the annotations haven't finished being added to the map. However, if it is nil, you probably don't care if an annotation that isn't even on screen is in front or not.
  2. You need to call bringSubviewToFront on the annotationView's superview, and not on self.view or even mapView, as neither of those are the superview of the annotationView.
Itay
  • 1,669
  • 5
  • 18
  • 23
  • that makes sense - thank you! I need not worry about the annotation being nil as previous zoom to region code ensures that when I call this code they will be on screen (at least for a fraction - as they are drawn). I'll give the code a whirl tomorrow. Many thanks for the reply. – Matt Facer Sep 15 '10 at 23:16
  • Important call bringSubviewToFront on annotationView.superview instead of annotationView – Zee Dec 11 '14 at 11:56
  • You might also want to add this if(![l isKindOfClass:[MKUserLocation class]]){ – mogile_oli Mar 30 '16 at 00:01
1

This worked much better for me:

setup annotation view layer's zPosition (annotationView.layer.zPosition) in:

- (MKAnnotationView *)mapView:(MKMapView *)theMapView viewForAnnotation:(id <MKAnnotation>)annotation
{
    // if it's the user location, just return nil.
    if ([annotation isKindOfClass:[MKUserLocation class]])
        return nil;

    MKAnnotationView *returnedAnnotationView = nil;
    returnedAnnotationView = [CUSTOMVIEW createViewAnnotationForMapView:self.mapView annotation:annotation];
    // SOME CUSTOM PROCESSING...
    returnedAnnotationView.layer.zPosition = 3;
    return returnedAnnotationView;
}

Note that I assume the default zPosition is 0. Setting to 3 made all the 3 markers show up on top for me.

mogile_oli
  • 2,148
  • 2
  • 21
  • 21
0
For IOS 11.0 onwards use below solution to bring the Custom Callout above all annotations.

Add z position observer where you are initialising the Custom callout 

[self.layer addObserver:self forKeyPath:@"zPosition" options:0 context:nil];


-(void)observeValueForKeyPath:(NSString *)keyPath
                      ofObject:(id)object
                        change:(NSDictionary *)change
                       context:(void *)context
{
    if(object == self.layer)
    {
        self.layer.zPosition = FLT_MAX;
    }
}