I am trying to get it so that when you rotate an iOS 7 map that the annotations rotate along with the camera heading. Imagine I had pin annotations that must point to North at all times.
This would seem simple at first, there should be a MKMapViewDelegate for getting the camera rotation but there isn't.
I've tried using the map delegates to then query the map view's camera.heading
object but firstly these delegates only seem to be called once before and once after a rotation gesture:
- (void)mapView:(MKMapView *)mapView regionWillChangeAnimated:(BOOL)animated
- (void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated
I also tried using KVO on the camera.heading object but this doesn't work and the camera object seems to be some kind of proxy object that only updates once the rotation gesture is complete.
My most successful method so far is to add a rotation gesture recogniser to calculate a rotation delta and use this with the camera heading reported at the beginning of the region change delegate. This works to a point but in OS 7 you can 'flick' your rotation gesture and it adds velocity which I can't seem to track. Is there any way to track the camera heading in real-time?
- (void)mapView:(MKMapView *)mapView regionWillChangeAnimated:(BOOL)animated
{
heading = self.mapView.camera.heading;
}
- (void)rotationHandler:(UIRotationGestureRecognizer *)gesture
{
if(gesture.state == UIGestureRecognizerStateChanged) {
CGFloat headingDelta = (gesture.rotation * (180.0/M_PI) );
headingDelta = fmod(headingDelta, 360.0);
CGFloat newHeading = heading - headingDelta;
[self updateCompassesWithHeading:actualHeading];
}
}
- (void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated
{
[self updateCompassesWithHeading:self.mapView.camera.heading];
}
Apple does not give real time updates to any map information unfortunately. Your best bet is to set up a CADisplayLink and update whatever you need to when it changes. Something like this.
@property (nonatomic) CLLocationDirection *previousHeading;
@property (nonatomic, strong) CADisplayLink *displayLink;
- (void)setUpDisplayLink
{
self.displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(displayLinkFired:)];
[displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes];
}
- (void)displayLinkFired:(id)sender
{
double difference = ABS(self.previousHeading - self.mapView.camera.heading);
if (difference < .001)
return;
self.previousHeading = self.mapView.camera.heading;
[self updateCompassesWithHeading:self.previousHeading];
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With