2012-07-30 9 views
7

Da - (void)mapViewDidFinishLoadingMap:(MKMapView *)mapView nicht aufgerufen wird, wenn die Kacheln aus dem Cache geladen werden, gibt es eine Möglichkeit zu wissen, wann alle Kacheln geladen (entweder vom Cache oder von den Mapping-Servern) und angezeigt wurden?Erkennen, wenn MapView-Kacheln angezeigt werden

Gibt es eine Delegierung, die anzeigt, dass Kacheln geladen wurden?

+2

Ich habe eingereicht Apple-Bug # 13.774.496 im Zusammenhang mit diesem und erstellt ein Beispiel-App des Problem weiterhin auf iOS6 existiert zeigen: https://github.com/iwasrobbed/MapKitDelegateBug – iwasrobbed

Antwort

4

Hier einige Quellcode schrieb ich:https://github.com/jonathanlking/mapViewTest

Warum Sie nicht über das Problem so denken; Wenn die Kartenansicht geändert wird, wird mapView:regionDidChangeAnimated: aufgerufen.

Von dort wird mapViewWillStartLoadingMap: aufgerufen werden.

Nächste mapViewDidFailLoadingMap:withError: oder mapViewDidFinishLoadingMap: wird aufgerufen, wenn die Kacheln vom Server abgeholt wurden.

Wenn jedoch keiner aufgerufen wird, können Sie davon ausgehen, dass die Kacheln aus dem Cache geladen werden.

+2

Danke, aber es gibt immer noch keine Möglichkeit, wissen, wann sie angezeigt werden. –

+0

Sie werden sofort angezeigt - wie sie zwischengespeichert werden. –

+2

Sorry, aber das funktioniert nicht. Ich habe die Internetverbindung auf meinem iPod Touch entfernt und auf eine Ebene gezoomt, auf der sich keine gecachten Kacheln befanden, und es stellt weiterhin fest, dass die Karte erfolgreich geladen wurde (in Ihrem Beispiel aus dem Cache). Dies ist ein Fehler von Apple. – iwasrobbed

2

Wie erwähnt, wird mapViewDidFinishLoadingMap manchmal überhaupt nicht aufgerufen, besonders wenn die Kartenkacheln bereits zwischengespeichert sind, und manchmal wird es mehrmals aufgerufen.

Ich merke, dass wenn es beim letzten Aufruf mehrfach aufgerufen wird, alle Kacheln gerendert werden. Ich denke, Sie können das zum Laufen bringen, wenn Sie einen 2-Sekunden-Timer einrichten, nachdem sich die Karte geändert hat. Deaktivieren Sie Interaktionen, damit sich die Zuordnung nicht ändert, und aktivieren Sie Benutzerinteraktionen, wenn der Zeitgeber deaktiviert wird.

Wenn mapViewDidFinishLoadingMap aufgerufen wird, setzen Sie den Timer erneut für 2 Sekunden in die Zukunft. Wenn der Timer schließlich ausgeschaltet wird, sollten Sie eine vollständig gerenderte Karte haben.

Sie sollten die anderen Rückrufe wie mapViewDidFailLoadingMap berücksichtigen. Testen Sie dies auch bei einer verrauschten Verbindung, da 2 Sekunden möglicherweise nicht lang genug sind, wenn es lange dauert, die Kacheln zu holen.

- (void)restartTimer 
{ 
    [self.finishLoadingTimer invalidate]; 
    self.finishLoadingTimer = [NSTimer scheduledTimerWithTimeInterval:2.0 
                   target:self 
                  selector:@selector(mapLoadingIsFinished) 
                  userInfo:nil 
                   repeats:NO]; 
} 

- (void)mapLoadingIsFinished 
{ 
    self.finishLoadingTimer = nil; 
    self.mapChanging = NO; 
    self.view.userInteractionEnabled = YES; 
} 

- (void)mapViewDidFinishLoadingMap:(MKMapView *)mapView 
{ 
    if (self.mapChanging) { 
     [self restartTimer]; 
    } 
} 

- (void)startLookingForMapChange 
{ 
    assert(self.mapChanging == NO); 
    if (self.mapChanging == NO) { 
     self.mapChanging = YES; 
     assert(self.finishLoadingTimer == nil); 
     self.view.userInteractionEnabled = NO; 
     [self restartTimer]; 
    } 
} 
+0

Dies funktioniert nicht in dem Szenario, in dem Sie die Internetverbindung verloren haben, sodass keine weiteren Kacheln geladen werden können. Es ruft den Delegierten immer noch an, dass die Karte vollständig geladen ist. – iwasrobbed

Verwandte Themen