5

I have an app with some annotations on it, and up until now they are just symbols that look good with the default behavior (e.g. like numbers and letters). Their directions are fixed in orientation with the device which is appropriate.

Now however I need some annotations that need to be fixed in orientation to the actual map, so if the map rotates, then the annotation symbols need to rotate with it (like an arrow indicating the flow of a river for example).

I don't want them to scale with the map like an overlay but I do want them to rotate with the map.

I need a solution that primarily works when the user manually rotates the map with their fingers, and also when it rotates due to be in tracking with heading mode.

On Google Maps (at least on android) this is very easy with a simple MarkerOptions.flat(true)

I am sure it won't be too much more difficult on ios, I hope.

Thanks in advance!

Kurt
  • 4,477
  • 2
  • 26
  • 34
  • I have come a bit closer by using a MkMapCamera inside of regionDidChangeAnimated, and rotating the relevant annotations there, but it looks funny while the user is rotating the map, it only "snaps" to the correct orientation after the user finished rotating. I want the exact same behavior as android MarkerOptions.flat(true), and I want the annotation's orientation to be locked to the map also while the user is rotating. – Kurt Jan 10 '15 at 19:09
  • And when I rotate them myself it is not just the symbol that rotates but the tooltip comes up at a funny angle! I am starting to think there is no way to do this! – Kurt Jan 11 '15 at 10:22
  • 1
    This would be a use case for an `MKOverlayRenderer`, I think. Just as an overlay polygon rotates with map data, you can align yourself according to the direction between two geographical points, thereby rotating with the map. If I can find time to test and prove it with an example, I'll promote this to an answer. – Tommy Jan 13 '15 at 05:05
  • Sounds interesting. I will experiment with it this weekend. Up until now I thought overlays always scale with the map which I don't want, but if it is possible to suppress scaling, then overlays could work for me. Thanks for the comment. – Kurt Jan 14 '15 at 07:23
  • 1
    my interpretation from the documentation is that you're in charge of the drawing if you don't use one of the built-in shapes, and can simply ignore `zoomScale`. But, as I say, I haven't actually tried. – Tommy Jan 14 '15 at 21:26
  • So I experimented with the MKOverlayRenderer and got a solution that I am still not really happy with. The icons get all distorted unless I recalculate the bounding rectangle for each symbol and its rotation myself. Ignoring zoomScale didn't help as the symbols scaled inappropriately anyway. I had to use zoomScale to compensate. And it still looks weird... There really is no solution until Apple catches up with Google and implements flat annotations. – Kurt Jan 19 '15 at 05:43

1 Answers1

6

Here's what I used for something similar.

- (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);
}

And then, this is called in regionDidChange etc.

Unfortunately, this solution doesn't rotate while the user is rotating the map, but it corrects itself afterwards to make sure it has the proper heading. I wrap some of the affineTransform into an animation block to make it look nice.

Hopefully this can help, or maybe help get you pointed in the right direction.

Logan
  • 52,262
  • 20
  • 99
  • 128
  • If you call your method in the mapViewDidChangeVisibleRegion(_:), the annotation rotates correctly, even if the user rotates the map. Thanks for the useful idea! – jason d Jul 27 '21 at 21:09