Rotate MapView using Compass orientation

2020-02-09 14:00发布

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?

5条回答
Melony?
2楼-- · 2020-02-09 14:15

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

查看更多
▲ chillily
3楼-- · 2020-02-09 14:24

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
4楼-- · 2020-02-09 14:31

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;
查看更多
Deceive 欺骗
5楼-- · 2020-02-09 14:32

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.

查看更多
地球回转人心会变
6楼-- · 2020-02-09 14:36

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
    }
}
查看更多
登录 后发表回答