Rotation of MapView can be implemented by setting mapView.transform = CGAffineTransformMakeRotation(alpha). This rotates the full mapView (including Callout, graphics...) on UIView-Base and can be hanged on your Compass with use of CLLocationManager.You can try my code in "ZüriPlan" - App available on App Store.PS: I block Interface rotation when Compass is active. Its a mess! Also deactivate Compass when Pushing your map away with NavigationController or if you leave MapView through TabViewController. Deactivate it when leaving the App or push the Standby button (AppDelegate Functions...) it's very Energy-hungry 😉My Code:Interface:@Interface MapViewController:UIViewController<CLLocationManagerDelegate>
//CLLocationManagerDelegate provides functions to listen to Heading/GPS Change
{
....
CGRect originalMapViewFrame; // Save the current mapView Size here
IBOutlet AGSMapView *mapView; //your AGSMapView Reference...
CLLocationManager *locationManager; //locationManager Instance
...
}
//Serve your LocationManager as retained Property to manage your Memory correctly, don't forgett to release it in your dealloc-Funciton
@property(retain) CLLocationManager *locationManager;
@end
Implementation:@implementation MapViewController
@synthesize locationManager; //generate property code
...
-(void) startHeading
{
//locationManager is an Object of Type CLLocationManager -> import CoreLocation
if (!self.locationManager) {
self.locationManager = [[[CLLocationManager alloc] init]autorelease];
self.locationManager.delegate = self;
}
// First: Backup current mapview Size. It will be restored on stopHeading
CGPoint origin = self.mapView.frame.origin;
CGSize size = self.mapView.frame.size;
originalMapViewFrame = CGRectMake(origin.x, origin.y, size.width, size.height);
//Blow up your map to a Square, this will hide white Areas when rotating your map
//The new size will be the diagonal length using Phytagoras...
CGFloat newWidth = floor(sqrt(pow(size.width, 2) + pow(size.height, 2)));
//Calculate new x and y origins
CGFloat x = origin.x - ((newWidth - size.width) /2);
CGFloat y = origin.y - ((newWidth - size.height) /2);
//Set the new Layoutinformation to your mapView
self.mapView.frame = CGRectMake(x, y, newWidth, newWidth);
//tell your LocationManager to start the updating
[self.locationManager startUpdatingHeading];
}
//Will be called from locationManager and updates every Heading Changed
-(void) locationManager: (CLLocationManager *)manager didUpdateHeading: (CLHeading *)newHeading
{
// Get your magneticHeading. If you need the "true" heading, use newHeading.trueHeading instead. But trueHeading only works, if GPS is enabled for your App and your Device is GPS ready...
float heading = newHeading.magneticHeading;
// You can use this block for smoother Rotation using a UIView Animation
[UIView beginAnimations:nil context:UIGraphicsGetCurrentContext()];
[UIView setAnimationCurve:UIViewAnimationCurveLinear];
[UIView setAnimationDuration:0.05];
//make some math (radial to degree or something...)
float rotation = -1.0f * M_PI * (heading) / 180.0f;
//Apply a rotation Transform to your map
self.mapView.transform = CGAffineTransformMakeRotation( rotation);
//Commit the animation
[UIView commitAnimations];
// if you need actual heading somewhere else, save it. otherwise you don't need this
self.heading = rotation;
}
//Stops heading
-(void) stopHeading
{
[self.locationManager stopUpdatingHeading];
//Remove Rotate Animation
self.mapView.transform = CGAffineTransformMakeRotation(0);
// Restore original Framedata for your mapView
self.mapView.frame = originalMapViewFrame;
}
@end