Is it possible to have an embedded MKMapView
rotate to always face the direction the iPhone is facing? Basically I want to mimic the Map app rotation feature on my own app.
I see that the iPhone SDK does not expose the functionality. However, I wonder if it would work to rotate the entire view using CGAffineTransformMakeRotate
. Would it affect tapping and zooming? Is there a better way?
To rotate the mapView but not the annotations you could use the following code to compensate for the maps rotation.
- (void)locationManager:(CLLocationManager *)manager
didUpdateHeading:(CLHeading *)newHeading
{
double rotation = newHeading.magneticHeading * 3.14159 / 180;
CGPoint anchorPoint = CGPointMake(0, -23); // The anchor point for your pin
[mapView setTransform:CGAffineTransformMakeRotation(-rotation)];
[[mapView annotations] enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
MKAnnotationView * view = [mapView viewForAnnotation:obj];
[view setTransform:CGAffineTransformMakeRotation(rotation)];
[view setCenterOffset:CGPointApplyAffineTransform(anchorPoint, CGAffineTransformMakeRotation(rotation))];
}];
}
Another sollution is using a new method that has been added in iOS 5 to MKMapView.
Take a look at: http://developer.apple.com/library/ios/#documentation/MapKit/Reference/MKMapView_Class/MKMapView/MKMapView.html
- (void)setUserTrackingMode:(MKUserTrackingMode)mode animated:(BOOL)animated;
I can confirm that it works fine. Here's the code that I'm using:
[mapView setTransform:CGAffineTransformMakeRotation(-1 * currentHeading.magneticHeading * 3.14159 / 180)];
mapView
is my MKMapView instance
Simple solution in swift 3.0. Make sure to put the line in mapViewDidFinishLoadingMap
or it will ignore it
public func mapViewDidFinishLoadingMap(_ mapView: MKMapView)
{
mapView.setUserTrackingMode(.followWithHeading, animated: false)
}
If you don't want the map to center on the user location you might do something like this
public func locationManager(_ manager: CLLocationManager, didUpdateHeading newHeading: CLHeading)
{
if(CLLocationCoordinate2DIsValid(mapView.centerCoordinate))
{
mapView.camera.heading = newHeading.trueHeading
}
}
If you look in the 3.0 iPhone Application Programming Guide under Device Support
you'll find information on the magnetometer (aka compass). Once you start getting heading information (through the didUpdateHeading
method) you should be able to get the compass data then use that to calculate the proper rotation transform value to apply to the map view.
Not sure if it handles zooming. In the standard map application I've noticed that compass heading tracking stops as soon as you start pinch-zooming.
Also, keep in mind that location directions are in degrees whereas transform rotation angles are in radians.
if you use a navigationVontroller try this:
//For Left button
MKUserTrackingBarButtonItem *buttonItem = [[MKUserTrackingBarButtonItem
alloc]initWithMapView:_mapView];
self.navigationItem.leftBarButtonItem = buttonItem;
// For Right Button
MKUserTrackingBarButtonItem *buttonItem = [[MKUserTrackingBarButtonItem
alloc]initWithMapView:_mapView];
self.navigationItem.rightBarButtonItem = buttonItem;
来源:https://stackoverflow.com/questions/1245461/rotate-mapview-using-compass-orientation