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