two support open one multiple manage how hours have different app iphone mapkit

iphone - open - support account twitter



¿Cómo se define el orden de superposición de MKAnnotationViews? (6)

Bajo iOS 11, la implementación de displayPriority rompió todas las soluciones que usan bringSubviewToFront o zPosition .

Si anula el CALayer de la vista de anotación, puede recuperar el control de zPosition desde el sistema operativo.

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 } } }

Tengo varias MKAnnotaciones (y sus vistas correspondientes) en mi mapa, y a veces se llena de gente. Ahora, las anotaciones en mi aplicación vienen en dos formas: algunas están destinadas a permanecer donde están, mientras que otras se moverán con el paso del tiempo. Prefiero tener los más estables visualmente en el fondo y los más móviles para pasar siempre delante de ellos.

Uno pensaría, tal vez, que las anotaciones agregadas más recientemente al mapa terminarían en la parte frontal (o alternativamente en la parte trasera, al menos) pero esto simplemente no parece ser la regla. Por lo que puedo decir, creo y agrego TODAS las anotaciones que no se mueven primero, y luego agrego algunas anotaciones en movimiento recién creadas, pero muchas de ellas (¡aunque no todas!) Terminan dibujadas debajo de las que permanecen en stock perpetuamente.

Curiosamente, cuando pasa el tiempo y se crean nuevas anotaciones en movimiento, tienden a gravitar más hacia la parte superior que las primeras, incluso si todos los objetos de anotación en movimiento se crearon solo después de que las partes no movidas ya se agregaron al mapa.

¿Alguien sabe un truco para alterar este extraño orden natural de las vistas de anotación en el mapa? Traté de buscar la API de Map Kit, pero no parece hablar de tal cosa.


Intente configurar zPosition de la vista de anotación (annotationView.layer.zPosition) en:

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


Me parece que este reordenamiento de las vistas de anotación causa que la llamada emergente que aparece cuando se hace clic en una de ellas deje de estar en la parte superior de todas las anotaciones. Incluso he intentado refinarlo para que en lugar de bringSubviewToFront y sendSubviewToBack , use insertSubview:aboveSubview e insertSubview:belowSubview: donde el segundo argumento es la primera anotaciónView en la lista. Esto parece causar mucho menos dispersión de adelante hacia atrás, pero las salidas de llamadas todavía aparecen bajo algunas anotaciones.


Ok, entonces para el método de uso de solución de MKMapViewDelegate

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

En este método, debe reorganizar AnnotationView después de que se haya agregado a mapKit View. Entonces, el código puede verse así:

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

Esto funciona para mí


Realmente necesitaba hacer esto, y ninguna de las respuestas (actuales) parecía proporcionar una implementación confiable. De alguna manera funcionaron, pero desplazar el mapa, seleccionar anotaciones o hacer zoom podría desordenar el orden nuevamente.

La solución final, de buen comportamiento, no fue tan trivial, por lo que simplemente describiré los pasos que tomé aquí. El orden de anotación que utiliza MKMapView no respeta el orden agregado, ni siquiera el orden de una propiedad de annotations anuladas. Asi que...

Pasos

• Crea un CADisplayLink
• Cada fotograma, reordena las anotaciones utilizando la capa zPosition y el orden de la vista en la matriz de subviews de subviews .
• Si la vista está seleccionada, promocionela al frente en su esquema de pedido
• Pulsar en las anotaciones sigue respetando el orden interno de MKMapView , a pesar de los cambios ya realizados. Para contrarrestar esto, agregue un MKMapViewDelegate
• En el método mapView:didSelect: del objeto delegado, compruebe si la anotación seleccionada es lo que desea que sea
• Puede averiguar la anotación correcta / priorizada ejecutando pruebas de aciertos en las anotaciones usted mismo, teniendo en cuenta su propio orden teniendo en cuenta
• Si la anotación seleccionada es correcta, excelente. De lo contrario, seleccione manualmente la anotación correcta utilizando selectAnnotation:animated:

Y ahí lo tienes. El método anterior parece funcionar bien, y el rendimiento alcanzado al ejecutar este cada cuadro no es tan malo. También puede considerar cambiar a MapBox, que creo que admite el orden de anotación, pero esto no siempre es una opción por varias razones.


Swift 3:

Obtuve ubicaciones de pin de API y tuve problemas similares, los pines que tenían que estar en la parte superior no. Pude resolverlo así.

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. } }

Espero que esto ayude