3

I'm displaying real time locations of city's buses on MKMapView. My app polls locations with certain interval and updates them on map. I'm trying to animate movement of the map annotations.

I have successfully animated movement with the following code found from this stackoverflow answer:

- (void)moveBusAnnotation:(TKLBus*)bus coordinate:(CLLocationCoordinate2D)coordinate {
    [UIView animateWithDuration:0.5f
    animations:^(void){
        bus.annotation.coordinate = coordinate;
    }];
}

Problem is that when user pans or zooms the map while animation is playing, the motion path of the annotation looks weird and buggy. Here's a demonstration:

map annotation animation

Notice how the map annotation follows a strange curve instead of straight line. Bus movement is simulated so ignore its strange position on map.

How can I make the animation look more natural or stop animations while map is panned/zoomed?

Edit: The animation seems to do the right thing. It looks weird just because the map annotation's next coordinate is moving while the animation plays. I think the solution would be to prevent animations while user is touching the screen.

Community
  • 1
  • 1
Kimmo
  • 1,886
  • 1
  • 21
  • 28

1 Answers1

1

Try this:

Set up a bool that will indicate wether the map is being used by the user:

@property (nonatomic, assign) BOOL userIsInteracting;

Then check the users touches in the map:

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    [super touchesBegan:touches withEvent:event];

    for (UITouch * touch in touches) 
    {
        CGPoint loc = [touch locationInView:_mapView];
        if ([_mapView pointInside:loc withEvent:event]) 
        {
            _userIsInteracting = YES;
            break;
        }
    }
}

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
    [super touchesEnded:touches withEvent:event];

    for (UITouch * touch in touches) 
    {
        CGPoint loc = [touch locationInView:_mapView];
        if ([_mapView pointInside:loc withEvent:event]) 
        {
            _userIsInteracting = NO;
            break;
        }
    }
}

Now you know when to animate the location in the map:

- (void)moveBusAnnotation:(TKLBus*)bus coordinate:(CLLocationCoordinate2D)coordinate 
{
    if (_userIsInteracting) return;

    [UIView animateWithDuration:0.5f
                     animations:^(void){
                     bus.annotation.coordinate = coordinate;
                     }];
}
freshking
  • 1,824
  • 18
  • 31