如何定义重叠MKAnnotationViews的顺序?

36 iphone mapkit

我的地图中有几个MKAnnotations(及其相应的视图),有时会非常拥挤.现在,我的应用程序中的注释有两种形式:一些注定要保持原样,而另一些则会随着时间的推移而移动.我希望在背景中有视觉上更稳定的,而移动的那些总是在它们前面传递.

也许会想到,最近添加到地图中的注释会最终到达前面(或者至少在最后面),但这似乎不是规则.据我所知,我首先创建并添加所有非移动注释,然后添加一些新实例化的移动注释,但其中许多(尽管不是全部!)最终都是在永久存货的情况下绘制的.

有趣的是,当时间流逝,然而创建新的移动注释时,它们倾向于更多地倾向于顶部而不是第一个 - 即使所有移动的注释对象仅在非移动部分已经添加到地图之后才创建.

有没有人知道改变地图上注释视图的奇怪自然顺序的技巧?我试图搜索Map Kit API,但它似乎没有提到这样的事情.

tt.*_*lew 41

好的,所以对于MKMapViewDelegate的解决方案使用方法


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

在此方法中,您应该在将AnnotationView添加到mapKit View后重新排列.所以,代码可能如下所示:


- (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];
      }
   }

}
Run Code Online (Sandbox Code Playgroud)

这适合我.


Jam*_*s H 18

在iOS 11下,执行displayPriority打破了使用bringSubviewToFront或的所有解决方案zPosition.

如果覆盖注释视图的CALayer,则可以从OS中重新控制zPosition.

class AnnotationView: MKAnnotationView {

    /// Override the layer factory for this class to return a custom CALayer class
    override class var layerClass: AnyClass {
        return ZPositionableLayer.self
    }

    /// convenience accessor for setting zPosition
    var stickyZPosition: CGFloat {
        get {
            return (self.layer as! ZPositionableLayer).stickyZPosition
        }
        set {
            (self.layer as! ZPositionableLayer).stickyZPosition = newValue
        }
    }

    /// force the pin to the front of the z-ordering in the map view
   func bringViewToFront() {
        superview?.bringSubview(toFront: self)
        stickyZPosition = CGFloat(1)
    }

    /// force the pin to the back of the z-ordering in the map view
   func setViewToDefaultZOrder() {
        stickyZPosition = CGFloat(0)
    }

}

/// iOS 11 automagically manages the CALayer zPosition, which breaks manual z-ordering.
/// This subclass just throws away any values which the OS sets for zPosition, and provides
/// a specialized accessor for setting the zPosition
private class ZPositionableLayer: CALayer {

    /// no-op accessor for setting the zPosition
    override var zPosition: CGFloat {
        get {
            return super.zPosition
        }
        set {
            // do nothing
        }
    }

    /// specialized accessor for setting the zPosition
    var stickyZPosition: CGFloat {
        get {
            return super.zPosition
        }
        set {
            super.zPosition = newValue
        }
    }
}
Run Code Online (Sandbox Code Playgroud)


hrc*_*hen 11

尝试在以下位置设置注释视图图层的zPosition(annotationView.layer.zPosition):

- (void)mapView:(MKMapView *)mapView didAddAnnotationViews:(NSArray *)views;
Run Code Online (Sandbox Code Playgroud)

  • 这对我有用.`bringSubviewToFront:`没有. (4认同)

小智 5

斯威夫特 3:

我从 API 获得了引脚位置,但我遇到了类似的问题,而必须位于顶部的引脚却没有。我能够像这样解决它。

var count = 0 // just so we don't get the same index in bottom pins
func mapView(_ mapView: MKMapView, didAdd views: [MKAnnotationView]) {  
    for view in views {
        view.layer.zPosition = CGFloat(count)
    }
    count += 1
    if count > 500 {
        count = 250 // just so we don't end up with 999999999999+ as a value for count, plus I have at least 30 pins that show at the same time and need to have lower Z-Index values than the top pins. 
    }

}
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助


Tru*_*an1 5

在委托功能中,您可以选择引脚以将其强制置于顶部:

func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView?` {
    ...
    if my annotation is the special one {
        annotationView.isSelected = true
    }
    ...
}
Run Code Online (Sandbox Code Playgroud)