Z-ordering of MKAnnotationViews

橙三吉。 提交于 2019-11-26 22:58:11

问题


I'm getting fairly frustrated with the limitations of MKMapKit. My current problem has to do with the z-ordering of annotation views, particularly as it relates to touches. If you accept the default z-order the mapkit gives you:

  1. The order appears random. The z-order is unrelated to the order the annotations were added.
  2. If one annotation ends up on top of another one, touching the top annotation generally brings up the callout for the bottom annotation. It seems like the hit detecting doesn't even respect the draw order. What's up with that?

I've tried solving #1 using something similar to the following code found on the web (which was designed to give some control over z-order)

- (void)mapView:(MKMapView *)mapView didAddAnnotationViews:(NSArray *)views {
   for (MKAnnotationView * annView in views) {
      TopBottomAnnotation * ann = (TopBottomAnnotation *) [annView annotation];
      if ([ann top]) {
         [[annView superview] bringSubviewToFront:annView];
      } else {
         [[annView superview] sendSubviewToBack:annView];
      }
   }

}

Running through the annotation views passed to mapView:didAddAnnotationViews: and adjusting their z-order does seem to fix #1. The problem is that now the callout views are no longer always on top to the annotation views. The MapKit seems to get very confused about the layers (callouts should be drawn in a layer above all annotation views). I can even figure out how it is getting confused since all the MKAnnotationViews you receive have the same superview (a private class MKOverlayView). You would think any reasonable design would draw the callouts about this overlay view.

Has anyone solved #1 or #2 successfully?


回答1:


If you have a custom annotationView (which sounds like you already have) you can try adding this:

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event 
{
    [self.superview bringSubviewToFront:self];
    [super touchesBegan:touches withEvent:event];
}

A side-effect is that each time a marker is touched it also pops to the front of the z-order, which actually is sensible since that's what the user is focusing on.




回答2:


Ramin, that is perfect for what I am trying to do. I did not have a custom annotation view defined though. I solved this by using a category and it worked perfect!

Here is the header:

#import <Foundation/Foundation.h> 
#import <MapKit/MapKit.h>


@interface MKPinAnnotationView (ZIndexFix)
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event; 
@end

And the Implementation:

#import "AEBMapViewCategory.h"
@implementation MKPinAnnotationView (ZIndexFix)
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event 
{
    [self.superview bringSubviewToFront:self];
    [super touchesBegan:touches withEvent:event];
}
@end



回答3:


Try another solution, setup annotation view layer's zPosition (annotationView.layer.zPosition) in:

(void)mapView:(MKMapView *)mapView didAddAnnotationViews:(NSArray *)views;



来源:https://stackoverflow.com/questions/1681565/z-ordering-of-mkannotationviews

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!