Jak definovat pořadí překrývání MKAnnotationViews?

hlasů
29

Mám několik MKAnnotations (a jejich odpovídající pohledy) v mé mapě, a to někdy dostane opravdu přeplněný. Nyní, anotace v mém app přijde ve dvou příchutích: někteří jsou povinni zůstat, kde jsou, zatímco jiní budou pohybovat jak čas pokračuje. Raději bych mít ty stálejší vizuálně v pozadí a ty, pohybující se vždy projít před nimi.

Člověk by si myslel, možná, že anotace nejnověji přidávají do mapy by skončit na přední (nebo alternativně na úplně vzadu, přinejmenším), ale to prostě nezdá se být pravidlem. Pokud je mi známo, tvořím a nejprve přidat všechny non-pohybovat anotace, a pak přidat nějaké nově instance pohybující anotací, ale mnoho z nich (i když ne všichni!) Skončí protahována za trvale nehybně ty.

Je zajímavé, že když jde o čas, a přesto vznikají nové pohyblivé poznámky, mají tendenci tíhnout více k vrcholu, než těch prvních - i kdyby se všechny pohyblivé objekty anotace byly vytvořeny až po nehybné části již byly přidány do mapy.

Ví někdo trik na změnu této podivné přirozený řád pohledů poznámek na mapě? Snažil jsem se hledat na Mapa Kit API, ale nezdá se, že mluvit o něčem takovém.

Položena 17/07/2009 v 20:33
zdroj uživatelem
V jiných jazycích...                            


7 odpovědí

hlasů
38

Ok, tak pro metodu použití řešení z MKMapViewDelegate


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

V této metodě je třeba uspořádat AnnotationView poté, co byl přidán do mapKit View. Takže, kód může vypadat takto:


- (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 funguje pro mě.

Odpovězeno 31/07/2009 v 17:09
zdroj uživatelem

hlasů
11

Pokusit se zPosition nastavení anotace pohled vrstvy (annotationView.layer.zPosition) v:

- (void)mapView:(MKMapView *)mapView didAddAnnotationViews:(NSArray *)views;
Odpovězeno 03/05/2013 v 11:40
zdroj uživatelem

hlasů
4

Swift 3:

Mám kolík místa z API a já měl podobné problémy, čepy, které měly být na vrcholu nebyly. Byl jsem schopen vyřešit to takhle.

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

}

Snad to pomůže

Odpovězeno 05/12/2016 v 21:06
zdroj uživatelem

hlasů
3

Pod iOS 11 se implementace displayPriorityzlomil všechna řešení, které používají bringSubviewToFrontči zPosition.

Pokud přepsat CALayer anotaci View, můžete zápasit kontrolu zPosition zpět z OS.

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
        }
    }
}
Odpovězeno 25/01/2018 v 23:23
zdroj uživatelem

hlasů
2

Já jsem k závěru, že toto přeskupení názory poznámek způsobí popisku, který se objeví, když člověk klikne na již být na vrcholu všech anotací. Dokonce jsem se snažil, aby místo toho ji rafinace bringSubviewToFronta sendSubviewToBack, mohu použít insertSubview:aboveSubviewa insertSubview:belowSubview:kde druhý argument je první annotationView v seznamu. To by mohlo způsobit mnohem menší zepředu dozadu rozptylu, ale výjezdům stále vyskočí pod nějakými poznámkami.

Odpovězeno 05/11/2009 v 15:21
zdroj uživatelem

hlasů
1

Ve funkci delegáta, můžete zvolit pin ji přinutit na vrcholu:

func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView?` {
    ...
    if my annotation is the special one {
        annotationView.isSelected = true
    }
    ...
}
Odpovězeno 18/02/2019 v 01:32
zdroj uživatelem

hlasů
0

Já opravdu potřeba to udělat, a žádný z (aktuální) odpovědí vypadal, že poskytuje spolehlivou realizaci. Jsou nějak funguje, ale rýžování mapy, možnosti poznámky, nebo přiblížení mohl zkazit pořadí znovu.

Konečný, dobře vychovaný řešení nebylo tak triviální, takže budu nastínit kroky I tady vzali. Anotace, které nařizuje MKMapViewpoužívá nerespektuje přidanou pořadí, nebo dokonce pořadí jako přepsat annotationsmajetku. Tak...


kroky

• Vytvořit CADisplayLink
• Každý snímek, pořadí anotací pomocí jak na zPosition vrstvy a zobrazení se objednává ve SuperView v subviewspoli.
• Je-li zvolen pohled, podporovat ji na přední straně ve vašem systému objednávání
• Klepnutím na anotací stále respektuje vnitřní MKMapViewuspořádání, a to navzdory již provedených změn. To zvrátí toto, přidejte MKMapViewDelegate
• V delegovat objektu mapView:didSelect:metodu, zkontrolujte, zda je vybraná poznámka je to, co jste to chtěli mít
• Můžete zjistit správný / prioritizovány anotaci spuštěním hit testy na anotace sami, se svým vlastním uspořádáním vzaty v úvahu
• je-li zvolen anotace je správná, skvělé. Pokud tomu tak není, ručně vybrat správný anotaci pomocíselectAnnotation:animated:


A tady to máte. Výše uvedený postup se zdá, že funguje dobře a výkon hit od spuštění tohoto každý snímek není tak špatné. Dalo by se také podívat na přechod na MapBox, které podle mého názoru podporuje anotace pořadí, ale to není vždy možnost z různých důvodů.

Odpovězeno 15/09/2017 v 01:54
zdroj uživatelem

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