18

I have an app that currently uses CGAffineTransformMakeRotation to manipulate a MKMapView in order to display the map with the correct orientation and size. With the release of iOS7 this method has become unreliable (map center keeps shifting). I am hoping to solve this with a more reliable solution.

Is there a way to rotate the map in code without using CGAffineTransformMakeRotation?

I looked at the MKMapCamera in hopes I could manipulate it into passing staic values to manipulate the map but there is no way to manually set the centerCoordinate and the eyeCoordinate.

Cœur
  • 37,241
  • 25
  • 195
  • 267
Andrin
  • 425
  • 1
  • 4
  • 15

1 Answers1

32

You can rotate and pitch the map by setting a new MKMapCamera with -setCamera:animated:.

To set the rotation, give it a new heading parameter:

- (void)viewDidAppear:(BOOL)animated // or wherever works for you
{
    [super viewDidAppear:animated];

    if ([mapView respondsToSelector:@selector(camera)]) {
        MKMapCamera *newCamera = [[mapView camera] copy];
        [newCamera setHeading:90.0]; // or newCamera.heading + 90.0 % 360.0
        [mapView setCamera:newCamera animated:YES];
    }
}

You can also do a more fancy zoom with pitch and altitude change, showing buildings:

- (void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];

    if ([mapView respondsToSelector:@selector(camera)]) {
        [mapView setShowsBuildings:YES];
        MKMapCamera *newCamera = [[mapView camera] copy];
        [newCamera setPitch:45.0];
        [newCamera setHeading:90.0];
        [newCamera setAltitude:500.0];
        [mapView setCamera:newCamera animated:YES];
    }

}
nevan king
  • 112,709
  • 45
  • 203
  • 241
  • 1
    @nevanking hello, why we make a copy of mapView camera? Why we just don't use this instance? Will it lead to problems with memory or some other things? – Dima Deplov Feb 26 '14 at 18:50
  • Whoever coded this is very inefficient. You should never create a new camera and set it the camera of the map. Instead you should [self.map.camera setHeading:198]; for better performance. Set values to the camera of the map directly. – coolcool1994 May 22 '14 at 11:03
  • 4
    @coolcool1994 I coded this and it's done this way for a reason, which you don't understand. If you do it your way, there's no animation. If you want an animation, you use the method `setCamera:animated:`. – nevan king May 22 '14 at 11:27
  • You can do [self.map.camera setHeading:198 animated:YES]; – coolcool1994 May 22 '14 at 11:41
  • 1
    @coolcool1994 You can try that but it won't build since `MKMapCamera` has no `setHeading:animated:` method. – nevan king May 22 '14 at 13:02
  • 1
    If only there were some sort of generic UIView method for animating any animatable property. – tooluser Jun 10 '14 at 15:51
  • @tooluser there is `[UIView animateWithDuration:time_in_seconds animations:^{ self.view.frame = newFrame; //other animations }];` (formatting doesn't come out quite right in the comments) – WolfLink Jul 24 '14 at 04:40
  • 6
    If only there were some way to make sarcasm more obvious. – tooluser Jul 24 '14 at 15:47
  • 1
    @tooluser Sarcasm or not, rotating a map by rotating its view is the wrong approach here. You'll end up with the compass in the wrong place and you can't change the pitch. Anyway, why bother when there's the perfectly good `setCamera:animated:`? – nevan king Jul 24 '14 at 18:09
  • My bad; I thought it was said earlier that MKCamera's properties were animatable. I never suggested animating the rotation of the map itself. That would, indeed, not work. – tooluser Jul 24 '14 at 21:57
  • I tried to animate map pitch and map heading using `animateWithDuration` and it changed them without animation. So I guess `setCamera:animated:` is the way. If anyone achieved it in a more efficient way, please share. Apple also does not list these properties as animatable: https://developer.apple.com/library/ios/documentation/cocoa/conceptual/coreanimation_guide/AnimatableProperties/AnimatableProperties.html#//apple_ref/doc/uid/TP40004514-CH11-SW4 – pckill Nov 09 '14 at 09:54
  • The problem with this solution is that it pollutes your view with that little compass in the upper right corner. You may not want that, for example if your app is a compass itself, with a map underlay. I don't see any way to turn it off in the documentation... – Greg Bell Nov 12 '14 at 09:25
  • @GregBell Can't you make the map view larger than the screen? – meaning-matters Mar 10 '17 at 19:45