iOS - Mapkit продолжает анимировать местоположение пользователя при изменении вида карты (прокрутка, масштабирование)

Я показываю местоположение пользователя на карте, используя координаты CLLocationManager. Каждый раз, когда я перемещаю или изменяю масштаб карты, значок местоположения пользователя (синий значок с эффектом сонара) продолжает исчезать, а затем снова воспроизводится на карте. (Я НЕ имею в виду эффект анимации сонара. Синяя точка буквально исчезает, а затем снова появляется).

Я не вызываю никаких других методов при прокрутке / масштабировании карты. При использовании точек останова в методе делегата карты вызывается только return nil:

- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation
{
    //User's Pin
    if([annotation class] == MKUserLocation.class) {
        return nil;
    }

....rest of my code here, nothing else is called as I am only plotting user at this time...
}

person JimmyJammed    schedule 01.05.2013    source источник


Ответы (3)


В моем первоначальном ответе я думал, что целью было заменить мигающую синюю точку, которая появляется, когда вы используете MKMapView на showUserLocation = YES и userTrackingMode = MKUserTrackingModeFollow. Поэтому я показал, как заменить его изображением или стандартным штифтом.

Но оказывается, что проблема не в том, что есть синяя точка, показывающая текущее местоположение, а в том, что ее анимация прерывается, появляется и исчезает, когда пользователь панорамирует и приближает карту.

Я видел такое поведение, если вы вызываете removeAnnotations и удаляете все аннотации (включая аннотацию, созданную системой MKUserLocation). Я также видел такое поведение, если выключить showUserLocation и снова включить.

OP указывает, что ни одна из этих ситуаций не применима, но для будущих читателей это несколько соображений, которые могут вызвать такое поведение.


Оригинальный ответ:

Самый простой ответ - убедиться, что ваш контроллер является delegate для вашего MKMapView, а затем определить viewForAnnotation, который обнаруживает MKUserLocation, и заменить представление аннотации тем, что вы хотите. Например, если у вас есть @"user.png" изображение, которое вы хотите показать, оно может выглядеть так:

- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation
{
    if ([annotation isKindOfClass:[MKUserLocation class]])
    {
        NSString *annotationIdentifier = @"userlocation";
        MKAnnotationView *annotationView = [mapView dequeueReusableAnnotationViewWithIdentifier:annotationIdentifier];
        if (annotationView)
        {
            annotationView.annotation = annotation;
        }
        else
        {
            annotationView = [[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:annotationIdentifier];
            annotationView.image = [UIImage imageNamed:@"user.png"];
        }

        return annotationView;
    }

    // again, if you had other annotation types, such as MKPointAnnotation,
    // handle them here

    if ([annotation isKindOfClass:[MKPointAnnotation class]])
    {
        ...
    }

    return nil;
}

Или, если вы хотите показать стандартный вывод, вы можете:

- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation
{
    if ([annotation isKindOfClass:[MKUserLocation class]])
    {
        if ([annotation isKindOfClass:[MKUserLocation class]])
        {
            NSString *annotationIdentifier = @"userlocation";
            MKAnnotationView *annotationView = [mapView dequeueReusableAnnotationViewWithIdentifier:annotationIdentifier];
            if (annotationView)
            {
                annotationView.annotation = annotation;
            }
            else
            {
                annotationView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:annotationIdentifier];
            }

            return annotationView;
        }
    }

    // again, if you had other annotation types, such as MKPointAnnotation,
    // handle them here

    if ([annotation isKindOfClass:[MKPointAnnotation class]])
    {
        ...
    }

    return nil;
}
person Rob    schedule 01.05.2013
comment
Выше предполагается, что вы использовали функцию отображения местоположения пользователя MKMapView. - person Rob; 01.05.2013
comment
Да, мой контроллер является делегатом, все остальные контакты отображаются нормально, а установка точек останова показывает, что в этом методе вызываются вещи. - person JimmyJammed; 02.05.2013
comment
Вот что я сейчас делаю для местоположения пользователя: if ([annotation isKindOfClass: [MKUserLocation class]]) {return nil; } - person JimmyJammed; 02.05.2013
comment
Но синяя точка пользователя по-прежнему исчезает и оживает каждый раз, когда я прокручиваю / масштабирую карту. - person JimmyJammed; 02.05.2013
comment
Привет, Роб, правильно. Я ДЕЙСТВИТЕЛЬНО хочу показать синюю точку, но я НЕ хочу, чтобы она исчезла и продолжала анимировать каждый раз при прокрутке / масштабировании карты. Я не использую removeAnnotations. Буквально НИЧЕГО (кроме viewForAnnotation) не вызывается, когда я прокручиваю / масштабирую карту. Поэтому не уверен, почему местоположение пользователя продолжает исчезать и снова анимируется - person JimmyJammed; 02.05.2013
comment
@JamesHickman Единственное, что я знаю по этой причине, - это удаление аннотаций (и случайно MKUserLocation в процессе) или установка любого из свойств MKMapView (например, showUserLocation). Но вы говорите, что ничего не делаете. Думаю, я могу только предложить вам начать с пустого приложения, добавить представление карты и посмотреть, будет ли у вас такое же поведение. Затем медленно добавляйте функции, пока вы снова не испытаете это поведение. Извините, у меня нет лучших предложений. Вы также запускаете службы определения местоположения? Может быть, попробуйте выключить это и посмотреть, изменится ли поведение. - person Rob; 02.05.2013
comment
@JamesHickman В качестве альтернативы, если вы хотите загрузить куда-нибудь свой проект целиком, я бы с удовольствием посмотрел, если хотите. - person Rob; 02.05.2013
comment
Я только устанавливаю для showUserLocation значение yes в методе viewDidLoad контроллера. Единственный вызываемый код - это загрузка данных пина (то есть координат и другой соответствующей информации), а затем настройка делегата mapview. Я думаю, что проблема не в повторной анимации местоположения пользователя, а в чем-то еще, что полностью сбрасывает карту. Я повторно разместил вопрос (поскольку исходный пост явно сбивал людей с толку) со всем приведенным здесь кодом: stackoverflow.com/questions/16328276/ - person JimmyJammed; 02.05.2013

Захватите аннотацию местоположения пользователя по умолчанию в методе делегата viewForAnnotation, чтобы она не отображалась на графике. Вы можете использовать логическое значение для включения и выключения или создать свою собственную аннотацию в тандеме с LocationManager. Эта ссылка должна направить вас на верный путь:

Местоположение пользователя Anno

person ninehundreds    schedule 01.05.2013
comment
Думаю, в этом вопросе некоторая путаница. См. Обновленный исходный пост. Я не пытаюсь изменить синюю точку пользователя. Мне просто интересно, почему он продолжает исчезать, а затем повторно анимироваться каждый раз, когда карта прокручивается / масштабируется. - person JimmyJammed; 02.05.2013

Если вы использовали стандартный mapciew.showsUserLocation = true; для рисования местоположения пользователя, и он скользит по экрану, а не пульсирует на месте, то это, вероятно, из-за вашего viewForAnnotation метода. Убедитесь, что вы анимируете только добавляемые булавки, а не местоположение пользователя, которое добавляет вид карты.

- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation
{
    if ([annotation isKindOfClass:[MKUserLocation class]])
    {
      return nil;
    }
    //do stuff to the annotations that you added
}
person Craig    schedule 01.05.2013
comment
Да, это то, что я сейчас делаю, но каждый раз, когда я перемещаю / масштабирую карту, он перезагружает местоположение пользователя и повторно анимирует его (так, чтобы синяя точка исчезла, затем снова анимируется и начинает пульсировать). Это дает подтекст перезагрузки, которого я не хочу. Предложения? - person JimmyJammed; 02.05.2013
comment
Я не уверен, что вы имеете в виду, говоря «реанимировать». Когда я включаю и выключаю отслеживание на карте Apple, точка появляется или исчезает на месте, она не скользит ниоткуда. Что еще делает ваш код? Какие-либо триггеры на карте завершают панорамирование или масштабирование? Сколько мест в вашем коде включает и выключает отслеживание? Вы должны проверить, не звонят ли они неожиданно. - person Craig; 02.05.2013
comment
Итак, обнаружена новая ошибка, которая может помочь ее решить. Я добавил на карту кучу булавок-пустышек. При начальной загрузке все они отображаются. Если я прокручиваю / масштабирую карту, все они исчезают и больше не появляются. Повторная анимация, о которой я говорю, - это просто исчезновение синей точки, затем появляется пузырек сонара (большой), затем появляется синяя точка, пузырек сонара сжимается и начинает анимироваться как обычно. - person JimmyJammed; 02.05.2013
comment
Как будто весь mapView перераспределяется ...? - person JimmyJammed; 02.05.2013
comment
Ничего, кроме метода делегата viewForAnnotation. Никакой другой код я не вызываю. Нигде в моем коде нет removeAnnotations или перераспределения карты. - person JimmyJammed; 02.05.2013