Cum de a defini ordinea de suprapunere MKAnnotationViews?

voturi
29

Am mai multe MKAnnotations (și punctele de vedere corespunzătoare) în harta mea, și, uneori, devine foarte aglomerat. Acum, adnotările în aplicația mea vin în două arome: unele sunt obligate să rămână în cazul în care acestea sunt, în timp ce altele se vor mișca odată cu trecerea timpului. Aș prefera să aibă cele mai stabile vizual în fundal și cele care se deplasează pentru a trece mereu în fața lor.

S-ar crede, probabil, că notațiile adăugate cel mai recent la harta va ajunge la partea din față (sau, alternativ, chiar la spate, cel puțin), dar acest lucru nu pare a fi doar regula. În ceea ce pot spune, am crea și adăugați toate adnotările, imobilă, mai întâi, și apoi se adaugă unele adnotări în mișcare nou-instanțiate, dar multe dintre ele (deși nu toate!) Sfârșesc trase în mod perpetuu cele țintuit.

Interesant, atunci când timpul trece, și totuși sunt create noi adnotări în mișcare, ele tind să graviteze mai mult la partea de sus decât cele primele - chiar și în cazul în care au fost create toate obiectele în mișcare de adnotare numai după ce părțile nonmoving au fost deja adăugate pe hartă.

Stie cineva un truc pentru a modifica această ordine naturală ciudat punctelor de vedere adnotare pe hartă? Am încercat să caute API Map Kit, dar nu pare să vorbească despre un astfel de lucru.

Întrebat 17/07/2009 la 20:33
sursa de către utilizator
În alte limbi...                            


7 răspunsuri

voturi
38

Ok, deci pentru metoda de utilizare soluție din MKMapViewDelegate


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

În această metodă ar trebui să rearanjați AnnotationView după ce a fost adăugat la mapKit View. Deci, cod poate arata ca acest lucru:


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

}

Aceasta funcționează pentru mine.

Publicat 31/07/2009 la 17:09
sursa de către utilizator

voturi
11

Încercați să zPosition de configurare vedere adnotare layer (annotationView.layer.zPosition) în:

- (void)mapView:(MKMapView *)mapView didAddAnnotationViews:(NSArray *)views;
Publicat 03/05/2013 la 11:40
sursa de către utilizator

voturi
4

Swift 3:

I a lua de la API locații pini și am fost cu probleme similare, pinii care a trebuit să fie pe partea de sus nu au fost. Am fost în stare să o rezolve așa.

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

}

Sper că acest lucru vă ajută

Publicat 05/12/2016 la 21:06
sursa de către utilizator

voturi
3

Sub iOS 11 punerea în aplicare a displayPriorityspart toate soluțiile care utilizează bringSubviewToFrontsau zPosition.

Dacă modificați CALayer vizualizarea adnotare, puteți lupta cu controlul zPosition înapoi din sistemul de operare.

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
        }
    }
}
Publicat 25/01/2018 la 23:23
sursa de către utilizator

voturi
2

Am constatat că această reordonare opiniile adnotare provoacă care apare înștiințarea atunci când cineva face clic să nu mai fie pe partea de sus a tuturor adnotărilor. Am încercat chiar de rafinare , astfel că , în loc bringSubviewToFrontși sendSubviewToBack, folosesc insertSubview:aboveSubviewși în insertSubview:belowSubview:cazul în care al doilea argument este primul annotationView din listă. Acest lucru ar părea să provoace mult mai puțin față spre spate împrăștiere, dar apelul outs încă pop - up în anumite adnotări.

Publicat 05/11/2009 la 15:21
sursa de către utilizator

voturi
1

În funcția de delegat, puteți selecta PIN-ul pentru a forța pe partea de sus:

func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView?` {
    ...
    if my annotation is the special one {
        annotationView.isSelected = true
    }
    ...
}
Publicat 18/02/2019 la 01:32
sursa de către utilizator

voturi
0

Chiar aveam nevoie pentru a face acest lucru, și nici unul dintre răspunsurile la (actuale) părea să asigure o punere în aplicare de încredere. Ei au un fel de lucrat, dar panoramare hartă, selectând adnotări sau mărire ar putea strica ordinea din nou.

Soluția finală, au comportat bine nu a fost atât de banal, așa că voi sublinia doar pașii am luat aici. Ordonarea adnotare care MKMapViewutilizează nu respectă ordinea adăugată, sau chiar de ordinul a unui overriden de annotationsproprietate. Asa de...


paşi

• Crearea unui CADisplayLink
• Fiecare cadru, reordona adnotări utilizând atât zPosition strat, și ordonarea vizualizarea în SuperView de subviewsmatrice.
• Dacă este selectată vizualizarea, promova în față în schema de comanda
• Prin atingerea adnotări încă respectă intern MKMapViewprin care se dispune, în ciuda deja făcute modificări. Pentru a contracara acest lucru, se adaugă un MKMapViewDelegate
• în obiectul delegat mapView:didSelect:metoda, verificați dacă adnotarea selectată este ceea ce ți - ar plăcea să fie
• Puteți da seama adnotare corecta / prioritizate prin rularea teste hit pe adnotările le cu propria ordonare luate în considerare
• în cazul în care adnotarea selectată este corectă, mare. Dacă nu, selectați manual adnotarea corectă utilizândselectAnnotation:animated:


Și nu-l ai. Metoda de mai sus pare să funcționeze bine, și performanță lovit de la rularea acestui fiecare cadru nu este prea rău. Ai putea uita, de asemenea, la trecerea la MapBox, pe care cred că sprijină adnotare de comanda, dar acest lucru nu este întotdeauna o opțiune pentru diverse motive.

Publicat 15/09/2017 la 01:54
sursa de către utilizator

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