2
votes

I am programmatically rotating a MKMapView using a simple NSTimer to constantly increment MKMapCamera's heading property which is working as expected (causes the map to slowly rotate around the Washington Monument).

Instead of having the map rotate around its center, I want it to rotate around the bottom of the map. The solution should be simple, double the height of the map and then rotate around its center which is now at the bottom of the screen. After doubling the height of the map it still rotates around the center of the screen rather than the center of the map frame.

It appears that Apple put extra logic into MKMapView to keep the "Legal" label on the bottom right, no matter what the map frame is, which I assume is also causing this issue.

Any ideas how I can force the map to rotate around the bottom of the map rather than the center?

- (void)setupMap {

    // Works as expected (rotates around center of screen)
    CGRect mapFrame = self.view.bounds; // works as expected

    // Doesn't work as expected (also rotates around the center of the screen)
    //mapFrame.size.height = self.view.frame.size.height*2;

    // Create/show MKMapView
    testMapView = [[MKMapView alloc] initWithFrame:mapFrame];
    [self.view addSubview:testMapView];

    // Zoom into the Washington Monument with a pitch of 60°
    MKMapCamera *aCamera = [MKMapCamera camera];
    [aCamera setCenterCoordinate:CLLocationCoordinate2DMake(38.8895, -77.0352)];
    [aCamera setAltitude:400];
    [aCamera setPitch:60];
    [testMapView setCamera:aCamera];

    // Begin rotating map every 1/10th of a second
    NSTimer *aTimer = [NSTimer timerWithTimeInterval:0.1 target:self selector:@selector(rotateMap) userInfo:nil repeats:YES];
    [[NSRunLoop currentRunLoop] addTimer:aTimer forMode:NSDefaultRunLoopMode];
}

- (void)rotateMap {
    MKMapCamera *aCamera = [testMapView camera];
    [aCamera setHeading:aCamera.heading+1];
    [testMapView setCamera:aCamera];
}
1
don't know, but think if you can solve it by creating a new camera at each timer intervall - AlexWien
just tried to create a new MKMapCamera each time rotateMap was called, however no difference. - Casey

1 Answers

1
votes

I realize this is an older question, but this is a very frustrating issue. Autolayout and MapKit are doing some funky stuff under the hood. I noticed that mapView rendering was automatically centering my map view to put user location in center of screen. no amount of offsets, constraints, transforms, supeviews, could get the map not to center in the screen, until I did this.

- (void)locationManager:(CLLocationManager *)manager didUpdateHeading:(CLHeading *)newHeading
{
    CLLocationDegrees heading = newHeading.trueHeading >= 0 ? newHeading.trueHeading : newHeading.magneticHeading;

    //ACCOUNT FOR LANDSCAPE ORIENTATION IN HEADING
    if(self.interfaceOrientation == UIInterfaceOrientationLandscapeRight){
              heading += 180;
              if(heading > 360) heading -= 360;
    }

    //OFFSET MAP
    CGPoint p = [_mapView convertCoordinate:_currentLocation toPointToView:_mapView];
    CGPoint p2 = CGPointMake(p.x, p.y - MAP_VERTICAL_OFFSET);
    CLLocationCoordinate2D t = [_mapView convertPoint:p2 toCoordinateFromView:_mapView];

    [_aCamera setHeading:heading];
    [_aCamera setCenterCoordinate:t];
    [_mapView setCamera:_aCamera];

}