2012-07-30 19 views
7

Od - (void)mapViewDidFinishLoadingMap:(MKMapView *)mapView nie jest wywoływana, gdy płytki są ładowane z pamięci podręcznej, czy jest jakiś sposób, aby wiedzieć, kiedy wszystkie płytki zostały załadowane (z pamięci podręcznej lub z serwerów mapujących) i wyświetlane?Wykrywanie, gdy wyświetlane są kafelki MapView

Czy są jakieś delegacje, które informują, że płytki zostały załadowane?

+2

I złożyli Jabłko Bug # 13774496 związane z tym i stworzył przykładową aplikację, aby pokazać problem nadal istnieje na iOS6: https://github.com/iwasrobbed/MapKitDelegateBug – iwasrobbed

Odpowiedz

4

Oto kod źródłowy pisałem:https://github.com/jonathanlking/mapViewTest

Dlaczego nie myślisz o problemie jak to;

Po zmianie widoku mapy zostanie wywołany mapView:regionDidChangeAnimated:.

Z tego miejsca zostanie wywołany mapViewWillStartLoadingMap:.

Następna mapViewDidFailLoadingMap:withError: lub mapViewDidFinishLoadingMap: zostanie wywołana, jeśli płytki zostały pobrane z serwera.

Jednak jeśli żadne z nich nie zostanie wywołane, można założyć, że kafelki są ładowane z pamięci podręcznej.

+2

Dzięki, ale nadal nie ma sposobu, aby wiedzieć, kiedy są wyświetlane. –

+0

Są wyświetlane natychmiast - ponieważ są buforowane. –

+2

Przepraszamy, ale to nie działa. Usunąłem połączenie internetowe na iPodzie Touch i powróciłem do poziomu, na którym nie było żadnych zbuforowanych kafli i nadal stwierdza się, że mapa zakończyła się pomyślnie (z pamięci podręcznej w twoim przykładzie). To jest błąd ze strony Apple. – iwasrobbed

2

Jak wspomniano, mapViewDidFinishLoadingMap czasami nie jest w ogóle wywoływana, szczególnie jeśli kafelki mapy są już buforowane, a czasami jest wywoływana wiele razy.

Zauważam, że gdy zostanie wywołana wiele razy przy ostatnim wywołaniu, wszystkie kafelki są renderowane. Więc myślę, że możesz to załatwić, jeśli ustawisz 2-sekundowy czas po zmianie mapy. Wyłącz interakcje, aby mapa nie zmieniała się, i włącz interakcje użytkownika, gdy timer się wyłączy.

Po wywołaniu mapViewDidFinishLoadingMap zresetuj licznik ponownie na 2 sekundy w przyszłości. Kiedy timer w końcu zgaśnie, powinieneś mieć w pełni wyrenderowaną mapę.

Będzie można rozważyć inne wywołania zwrotne, takie jak mapViewDidFailLoadingMap. Przetestuj to również na hałaśliwym połączeniu, ponieważ 2 sekundy mogą nie być wystarczająco długie, jeśli pobieranie płytek zajmuje dużo czasu.

- (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

Nie działa to w przypadku scenariusza, w którym utracono połączenie z Internetem, aby nie można było załadować większej liczby płytek. Nadal dzwoni do delegata mówiącego, że mapa jest w pełni załadowana. – iwasrobbed