Jak określić kolejność nakładania MKAnnotationViews?

głosy
29

Mam kilka MKAnnotations (i odpowiadające im wyświetleń) w mojej mapie, a czasami robi się naprawdę tłoczno. Teraz, adnotacje w mojej aplikacji są w dwóch smakach: niektórzy mają obowiązek pozostać tam, gdzie są, podczas gdy inni będą poruszać się w miarę upływu czasu. Wolałbym mieć bardziej stabilne te wizualnie w tle i te poruszające się zawsze przechodzą przed nimi.

Można by pomyśleć, być może, że adnotacje ostatnio dodane do mapy skończy się do przodu (lub alternatywnie na samym końcu, przynajmniej), ale to po prostu nie wydają się być regułą. O ile mogę powiedzieć, tworzę i dodać wszystkich non poruszających się adnotacje, a potem dodać kilka nowo instancja poruszających się adnotacje, ale wiele z nich (choć nie wszystkich!) W końcu wyciągnąć pod wiecznie nieruchomo nich.

Co ciekawe, gdy z upływem czasu, a jednak nowe ruchome adnotacje są tworzone, mają tendencję do skłaniają się bardziej do góry niż tych pierwszych - nawet jeśli wszystkie ruchome obiekty adnotacji zostały stworzone tylko po nieruchome części zostały już dodane do mapy.

Czy ktoś wie trick aby zmienić ten dziwny naturalny porządek widokach adnotacji na mapie? Próbowałem szukać Kit API Mapa, ale nie wydaje się mówić o czymś takim.

Utwórz 17/07/2009 o 20:33
źródło użytkownik
W innych językach...                            


7 odpowiedzi

głosy
38

Ok, dla metody stosowania roztworu z MKMapViewDelegate


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

W tej metodzie należy zmienić AnnotationView po dodaniu go do mapKit View. Tak, kod może wyglądać następująco:


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

}

To działa na mnie.

Odpowiedział 31/07/2009 o 17:09
źródło użytkownik

głosy
11

Spróbuj zPosition konfiguracji widoku opisu warstwy (annotationView.layer.zPosition) w:

- (void)mapView:(MKMapView *)mapView didAddAnnotationViews:(NSArray *)views;
Odpowiedział 03/05/2013 o 11:40
źródło użytkownik

głosy
4

Swift 3:

I dostać lokalizacje pin z API i miałem podobne problemy, kołki, które miały być na szczycie nie było. Udało mi się go rozwiązać w ten sposób.

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

}

Mam nadzieję że to pomoże

Odpowiedział 05/12/2016 o 21:06
źródło użytkownik

głosy
3

Pod iOS 11, realizacja displayPrioritypobił wszelkie rozwiązania, które używają bringSubviewToFrontlub zPosition.

Jeśli zastąpi widoku adnotacji w CALayer można mocować kontrolę zPosition powrotem od systemu operacyjnego.

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
        }
    }
}
Odpowiedział 25/01/2018 o 23:23
źródło użytkownik

głosy
2

Jestem stwierdzenia, że ta zmiana kolejności widoki adnotacji powoduje objaśnienie, które pojawia się po kliknięciu na jeden ma już nie być na szczycie wszystkich adnotacji. Ja nawet nie próbował udoskonalić go tak, że zamiast bringSubviewToFronti sendSubviewToBackużywam insertSubview:aboveSubviewi insertSubview:belowSubview:gdzie drugi argument jest pierwszym annotationView na liście. To wydaje się powodować znacznie mniej rozpraszające przodu do tyłu, ale wezwania do wciąż pojawiają się w pewnych adnotacji.

Odpowiedział 05/11/2009 o 15:21
źródło użytkownik

głosy
1

W funkcji delegata, można wybrać PIN, aby zmusić go na górze:

func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView?` {
    ...
    if my annotation is the special one {
        annotationView.isSelected = true
    }
    ...
}
Odpowiedział 18/02/2019 o 01:32
źródło użytkownik

głosy
0

I naprawdę potrzebne, aby to zrobić, a żadna z odpowiedzi (bieżących) wydawało się zapewnić rzetelną realizację. Oni jakby pracował, ale panoramowanie mapę, wybierając adnotacje lub powiększanie może zepsuć kolejność ponownie.

Ostateczna, dobrze wychowane rozwiązanie nie było tak banalne, więc będę po prostu przedstawić kroki wziąłem tutaj. Kolejność adnotacja, że MKMapViewużywa nie przestrzega dodaną porządku, a nawet kolejność w nadpisane annotationsnieruchomości. Więc...


Kroki

• Tworzenie CADisplayLink
• co ramkę, kolejność adnotacji przy użyciu zarówno z zPosition warstwy i kolejność widoku jest w Superview na subviewstablicy.
• Jeśli zostanie wybrany widok, promować go do przodu w swoim schematem zamawiania
• Stuknięcie adnotacji nadal szanuje wewnętrznego MKMapViewuporządkowania, mimo już dokonanych zmian. Aby temu przeciwdziałać, należy dodać MKMapViewDelegate
: • w obiekcie Delegatury mapView:didSelect:metody, należy sprawdzić, czy wybrany adnotacji to, co chcesz go mieć
• Można dowiedzieć się poprawić / priorytet adnotacji uruchamiając testy wytrzymałości na adnotacje siebie, z własnego zamawiania brane pod uwagę
• Jeśli wybrany adnotacja jest poprawna, to świetnie. Jeśli nie, należy ręcznie wybrać właściwą adnotację korzystaniaselectAnnotation:animated:


I tam masz. Powyższa metoda wydaje się działać dobrze, a hitem wydajność z uruchomieniem tego każdą klatkę nie jest tak źle. Można też spojrzeć na włączeniu do MapBox, która wierzę obsługuje adnotacji uporządkowanie, ale nie zawsze jest to opcja dla różnych powodów.

Odpowiedział 15/09/2017 o 01:54
źródło użytkownik

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more