2010-02-08 23 views
8

Sto mappando oltre 500 punti su una mappa utilizzando mapkit. Lo zoom è un po 'nervoso rispetto all'app nativa di Google Maps. Ho scoperto cosa sta causando la lentezza. Sto aggiungendo le annotazioni personalizzate in modo che possa poi aggiungere vari colori pin e pulsanti per le viste di dettaglio:Toubleshooting prestazioni del mapkit

- (MKAnnotationView *) mapView:(MKMapView *)mapView viewForAnnotation:(AddressNote *) annotation { 
    MKPinAnnotationView *annView=[[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:@"currentlocation"]; 
    annView.pinColor = MKPinAnnotationColorGreen; 
    annView.animatesDrop=TRUE; 
    annView.canShowCallout = YES; 
    annView.calloutOffset = CGPointMake(-5, 5); 
    return annView; 
} 

Se commento il codice di cui sopra, tutto funziona bene. Molto morbido con lo zoom in/out. Devo aggiungere annotazioni in modo diverso per migliorare le prestazioni?

risposta

1

Mi sembra che l'aggiunta di 500 punti mappa a una sezione di una mappa non abbia senso la dimensione dello schermo dell'iPhone. Non è possibile visualizzarlo o anche fare clic sull'annotazione giusta.

Non riesci a guardare il livello di zoom e il centro della mappa e quindi decidere di aggiungere solo un sottoinsieme di annotazioni alla mappa?

Penso di aver visto anche altre app farlo.

+0

Puoi spiegare come saresti mai in grado di eseguire quel tipo di caricamento pigro? – user230949

+1

MKMapView recapita i messaggi al proprio delegato ogni volta che la mappa scorre. Ogni volta che ciò accade, memorizza i delta di latitudine e longitudine della vista in modo da conoscere la vendita della mappa. Prima di memorizzare il valore, controllare se la scala della mappa è cresciuta o ridotta abbastanza da dover regolare il numero di annotazioni. Se è così, basta fare un calcolo del livello di dettaglio. Esegui l'elenco di annotazioni e combina quelli che si trovano a una certa distanza l'uno dall'altro in una nuova annotazione che rappresenta tutti loro. Se l'utente esegue lo zoom indietro, scambialo per le annotazioni originali. – VictorB

2

Penso che St3fan sia corretto. In teoria puoi continuare ad aggiungere annotazioni alla mappa e lasciare che la vista gestisca la visualizzazione di esse, ma la realtà è che è meglio se si tiene un po 'giù il conto, 500 sullo schermo in una sola volta sarebbero troppe da vedere comunque.

Tuttavia c'è un altro passo per provare - assicurarsi che tutti i punti di vista di annotazione hanno impostato opaca su YES in questo modo:

annView.opaque = YES; 
+0

Hai frainteso la domanda. Non ci sono 500 pin nell'area di visualizzazione. Ce ne sono solo alcuni. Se fai lo zoom indietro abbastanza, vedrai tutti i 500. annView.opaque = YES non ha aiutato. – user230949

+0

Quindi è necessario controllare il numero di mappe in una volta, dopo aver eseguito lo zoom in cui alcuni non sono visibili, è necessario rimuoverli. Ecco perché stavo parlando di come tecnicamente è stato creato per permetterti di fare quello che stai facendo - semplicemente aggiungendo molte annotazioni in cui alcuni sono fuori schermo - ma per le prestazioni la realtà è che non puoi avere tante annotazioni su una mappa e farlo eseguire beh, quindi devi gestire in una certa misura le annotazioni che la mappa conosce davvero. –

+0

Ok, sì - sono d'accordo. Ma come posso gestirli, quindi so quali caricare e quali no? Tutti i miei punti sono in un array. C'è qualcosa legato a loro che dice che questi punti sono nell'area di visualizzazione, carica le loro annotazioni. Questi non sono, rimuovi le loro annotazioni. – user230949

6

500 annotazioni è probabilmente troppi, ma non così tanti che le prestazioni soffre quando ne stai visualizzando solo alcuni. Tuttavia, si dovrebbe utilizzare dequeueing con le annotazioni per migliorare le prestazioni

- (MKAnnotationView *)mapView:(MKMapView *)mapView 
      viewForAnnotation:(id <MKAnnotation>)annotation 
{ 
    MKPinAnnotationView *view = nil; 
    if (annotation != mapView.userLocation) { 
     view = (MKPinAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:@"identifier"]; 
     if (nil == view) { 
      view = [[[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:@"identifier"] autorelease]; 
     } 
     [view setPinColor:MKPinAnnotationColorGreen]; 
     [view setCanShowCallout:YES]; 
     [view setAnimatesDrop:NO]; 
    } 
    else { 
     // Do something with the user location view 
    } 
    return view; 
} 

Inoltre, con 500 pin, l'animazione goccia richiede molto tempo per terminare. Dovresti disattivarlo con [view setAnimatesDrop:NO]

+2

Grazie, tuttavia, la rimozione della decodifica non aiuta le prestazioni. Sono consapevole del fatto che il gran numero di annotazioni sta causando il calo delle prestazioni. Posso diminuire a 100 e ottenere buone prestazioni. Quando l'area di visualizzazione della mappa cambia, ho bisogno di un modo per caricare annotazioni per i punti che stanno venendo in vista. Hai bisogno di un carico pigro ma mapkit non è amichevole per quel tipo di cose. – user230949

+2

La dequeue aiuta le prestazioni, perché altrimenti la utilizzeresti?"Il riutilizzo delle viste di annotazione offre significativi miglioramenti delle prestazioni durante lo scorrimento evitando la creazione di nuovi oggetti di visualizzazione durante questa operazione critica". http://developer.apple.com/iphone/library/documentation/MapKit/Reference/MKAnnotationView_Class/Reference/Reference.html –

3

Ho scritto un'app per iPhone per un cliente e abbiamo incluso uno store locator per uno dei loro marchi di negozio. Include 501 posizioni e mentre l'animazione può essere un po 'a scatti quando si esegue lo zoom per visualizzare gli interi Stati Uniti, è perfettamente ingrandito fino al livello di stato, dove sono visibili solo una manciata di spilli.

I tasti:

  • Zoom l'utente nella loro posizione corrente prima di aggiungere le proprie annotazioni.
  • Riutilizzare le viste di annotazione utilizzando dequeueReusableAnnotationViewWithIdentifier:.

Per raggiungere il primo punto, è necessario attivare gli aggiornamenti di posizione e impostare un flag quando si riceve il primo. Animare la mappa in quella posizione utilizzando un'area estesa per la propria app, quindi in mapView:regionDidChangeAnimated:, verificare se è ancora necessario aggiungere le annotazioni e che la posizione corrente è stata aggiornata prima di chiamare addAnnotation:.

Se non è possibile o non si desidera ingrandire la posizione dell'utente, è possibile filtrare le annotazioni visualizzate al livello più alto e aggiungere solo annotazioni aggiuntive mentre l'utente esegue lo zoom in avanti?

A proposito, credo che tu abbia una perdita di memoria nel tuo codice come pubblicato sopra.Anche se non si desidera utilizzare il meccanismo di rimozione, la vista restituita da mapView:viewForAnnotation: deve essere autorizzata.

1

Se non si rimuovono annotazioni non visualizzate dall'utente dalla vista, questa è una cosa da fare per mezzo di MKMapViewDelegate. Se le prestazioni diminuiscono quando si effettua lo zoom indietro a livello di paese, è possibile che si desideri presentare informazioni aggregate su livelli di zoom> alcuni valori const, ad es. invece di 30 annotazioni entro 10 miglia quadrate mostra una singola annotazione come [30 something].