Как реализовать MKAnnotationViews, которые вращаются вместе с картой

У меня есть приложение с некоторыми аннотациями, и до сих пор это были просто символы, которые хорошо смотрятся с поведением по умолчанию (например, цифры и буквы). Их направления фиксируются в ориентации соответствующим устройством.

Однако теперь мне нужны некоторые аннотации, которые нужно зафиксировать в ориентации относительно фактической карты, поэтому, если карта вращается, символы аннотаций должны вращаться вместе с ней (например, стрелка, указывающая течение реки).

Я не хочу, чтобы они масштабировались вместе с картой, как наложение, но я хочу, чтобы они вращались вместе с картой.

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

На Google Maps (по крайней мере, на Android) это очень просто с помощью простого MarkerOptions.flat(true)

Я уверен, что это не будет намного сложнее на ios, я надеюсь.

Заранее спасибо!


person Kurt    schedule 10.01.2015    source источник
comment
Я подошел немного ближе, используя MkMapCamera внутри regionDidChangeAnimated и вращая там соответствующие аннотации, но это выглядит забавно, пока пользователь вращает карту, она привязывается к правильной ориентации только после того, как пользователь закончил вращение. Я хочу точно такое же поведение, как и Android MarkerOptions.flat(true), и я хочу, чтобы ориентация аннотации была привязана к карте также во время вращения пользователя.   -  person Kurt    schedule 10.01.2015
comment
И когда я поворачиваю их сам, вращается не только символ, но и всплывающая подсказка появляется под забавным углом! Я начинаю думать, что нет никакого способа сделать это!   -  person Kurt    schedule 11.01.2015
comment
Я думаю, это был бы вариант использования MKOverlayRenderer. Подобно тому, как наложенный многоугольник вращается с данными карты, вы можете выровнять себя в соответствии с направлением между двумя географическими точками, таким образом вращаясь вместе с картой. Если я найду время, чтобы протестировать и доказать это на примере, я подниму это до ответа.   -  person Tommy    schedule 13.01.2015
comment
Звучит интересно. В эти выходные буду экспериментировать. До сих пор я думал, что оверлеи всегда масштабируются вместе с картой, которую я не хочу, но если можно подавить масштабирование, то оверлеи могут работать на меня. Спасибо за комментарий.   -  person Kurt    schedule 14.01.2015
comment
моя интерпретация из документации заключается в том, что вы отвечаете за рисунок, если не используете одну из встроенных фигур и можете просто игнорировать zoomScale. Но, как я уже сказал, я на самом деле не пробовал.   -  person Tommy    schedule 15.01.2015
comment
Так что я поэкспериментировал с MKOverlayRenderer и получил решение, которым я до сих пор не очень доволен. Все значки искажаются, если я сам не пересчитаю ограничивающий прямоугольник для каждого символа и его поворот. Игнорирование zoomScale не помогло, так как символы все равно масштабировались неправильно. Мне пришлось использовать zoomScale для компенсации. И это все еще выглядит странно... Решения действительно не будет, пока Apple не догонит Google и не внедрит плоские аннотации.   -  person Kurt    schedule 19.01.2015


Ответы (1)


Вот что я использовал для чего-то подобного.

- (void)rotateAnnotationView:(MKAnnotationView *)annotationView toHeading:(double)heading
{
    // Convert mapHeading to 360 degree scale.
    CGFloat mapHeading = self.mapView.camera.heading;
    if (mapHeading < 0) {
        mapHeading = fabs(mapHeading);
    } else if (mapHeading > 0) {
        mapHeading = 360 - mapHeading;
    }

    CGFloat offsetHeading = (heading + mapHeading);
    while (offsetHeading > 360.0) {
        offsetHeading -= 360.0;
    }

    CGFloat headingInRadians = offsetHeading * M_PI / 180;
    annotationView.layer.affineTransform = CGAffineTransformMakeRotation(headingInRadians);
}

И затем это вызывается в regionDidChange и т. д.

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

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

person Logan    schedule 19.01.2015
comment
Если вы вызываете свой метод в mapViewDidChangeVisibleRegion(_:), аннотация поворачивается правильно, даже если пользователь поворачивает карту. Спасибо за полезную идею! - person jason d; 28.07.2021