Car (Annotation) animation (like uber app) not working
Asked Answered
S

3

25

I made one demo project (from Moving-MKAnnotationView demo on github) for moving car on map following is its link

https://github.com/pratikbhiyani/Moving-MKAnnotationView

I edit my code on the basis of given answer by vinaut but still problem is that when we zoom or scroll the map animation get distract in ios 7 and in ios 6 when we zoom or scroll the map annotation set to its original angle for a while.

Below is a screen shot of my Demo Project

enter image description here

Here is some code i change

- (void) setPosition : (id) posValue;
{
    NSLog(@"set position");

    //extract the mapPoint from this dummy (wrapper) CGPoint struct
    MKMapPoint mapPoint = *(MKMapPoint*)[(NSValue*)posValue pointerValue];

    CLLocationCoordinate2D coord = MKCoordinateForMapPoint(mapPoint);
    CGPoint toPos;
    if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7) {

        toPos = [self.mapView convertCoordinate:coord toPointToView:self.mapView];
    }
    else
    {
        CGFloat zoomFactor =  self.mapView.visibleMapRect.size.width / self.mapView.bounds.size.width;
        toPos.x = mapPoint.x/zoomFactor;
        toPos.y = mapPoint.y/zoomFactor;
    }



    [self setTransform:CGAffineTransformMakeRotation([self getHeadingForDirectionFromCoordinate:MKCoordinateForMapPoint(previousPoint) toCoordinate: MKCoordinateForMapPoint(mapPoint)])];

    if (MKMapRectContainsPoint(self.mapView.visibleMapRect, mapPoint)) {

        CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"position"];

        animation.fromValue = [NSValue valueWithCGPoint:self.center];
        animation.toValue = [NSValue valueWithCGPoint:toPos];
        animation.duration = 1.0;
        animation.delegate = self;
        animation.fillMode = kCAFillModeForwards;
        //[self.layer removeAllAnimations];
        [self.layer addAnimation:animation forKey:POSITIONKEY];

        //NSLog(@"setPosition ANIMATED %x from (%f, %f) to (%f, %f)", self, self.center.x, self.center.y, toPos.x, toPos.y);
    }

    self.center = toPos;

    previousPoint = mapPoint;
}

My goal is to move car same like in uber app.

Stirk answered 9/10, 2013 at 9:29 Comment(7)
So what is the problem? Your annotations disappear when you move the map?Dierdredieresis
yeah. and its not show smooth animation like it shows in ios 6;Rabbi
Try to use translation transform instead of repositioning...Esmeralda
can you post your code of animation? and how you detect that car need to rotate like on edge of the road ?Vinegar
github.com/pratikbhiyani/Moving-MKAnnotationViewRabbi
it is running on pre defined coordinates...Rabbi
can you give idea to move pin using lat long which i get from api instand of pre define coordinates? for swiftIndividualize
C
14

It seems that something changed with the conversion functions for CLCoordinate2D/MKMapPoint/CGPoint...

Detecting a point in a MKPolygon broke with iOS7 (CGPathContainsPoint)

The annotation disappears because the conversion beetween MkMapPoints and CGIPoints does not work anymore, if you log the "position" of the CALayer you will get points way outside the view. No idea why it works when doing touch events.

If you change the function to :

    - (void) setPosition : (id) posValue; 
{
    //extract the mapPoint from this dummy (wrapper) CGPoint struct
    MKMapPoint mapPoint = *(MKMapPoint*)[(NSValue*)posValue pointerValue];  
    CLLocationCoordinate2D coord = MKCoordinateForMapPoint(mapPoint);

    CGPoint toPos = [self.mapView convertCoordinate:coord toPointToView:self.mapView];


    if (MKMapRectContainsPoint(self.mapView.visibleMapRect, mapPoint)) {

        CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"position"];

        animation.fromValue = [NSValue valueWithCGPoint:self.center];
        animation.toValue = [NSValue valueWithCGPoint:toPos];   
        animation.duration = 0.8;
        animation.delegate = self;
        animation.fillMode = kCAFillModeForwards;
        //[self.layer removeAllAnimations];
        [self.layer addAnimation:animation forKey:POSITIONKEY];

        //NSLog(@"setPosition ANIMATED %x from (%f, %f) to (%f, %f)", self, self.center.x, self.center.y, toPos.x, toPos.y);
    }   

    self.center = toPos;


}

It should be working again.

County answered 11/10, 2013 at 19:47 Comment(5)
hey thanks for answer but the problem with your code is the annotation distract from the path when map move.Rabbi
I don't know how it was supposed to behave in iOS 6. I pointed out the reason why the annotation it was not showing, you should be able to modify the code as you see fit knowing that. For example, if you don't want the annotation to update when panning or zooming, just have a property keeping track of the current mapView.visibleRect and compare it to the new value in setPosition, and do not run the animation if it has changed. Give it a shot and let me know if you succeed.County
In ios 6 its not distract from path when panning or zooming. and I can't stop animation. it is responsible for smooth driving.Rabbi
hey friend , You are close to answer so +50 for you :)Rabbi
Hey sorry for unaccept your answer but i will accept the answer after the completion of bounty.Rabbi
T
14

I'm the original contributor to Moving-MKAnnotationView (https://github.com/100grams/Moving-MKAnnotationView.git). This component was originally written using iOS4.3 and a lot has changed since. :-)

The root cause here was the conversion from MKMapPoint to CGPoint (screen coordinates). Although the code worked before, it breaks on iOS7 and I fixed it by using this to convert the lat/lon coordinate to screen coordinates:

convertCoordinate:toPointToView:

I've committed this fix, with a few other updates, to https://github.com/100grams/Moving-MKAnnotationView.git so it now works on iOS7/Xcode5.

Teal answered 22/10, 2013 at 15:57 Comment(6)
thanks for reply. its very nice demo.but problem is when theGroup.duration = 0.2 and when i increase duration to 1.0 for smooth animation , annotation distract from path on scalling or zooming the map.Rabbi
Yes that is indeed a caveat. I guess you should abort/stop any animation while the map is being panned/zoomed to avoid this side effect.Teal
Yes I tried it with remove animation but Unfortunately it shows same distraction :(Rabbi
Did you try to hide the moving annotations, i.e. set alpha=0 while map is panning/zooming?Teal
I want to add cars on the map and show their movement but the problem is that I am getting the position of cars from an api.So I want to animate cars through the latitude and longitude that I am getting from that api.How can I achieve that?Any help will be much appreciated.Moldau
github.com/100grams/Moving-MKAnnotationView.git nice demo but can you give idea to move pin using lat long which i get from api instand of pre define coordinates? for swiftIndividualize
D
1

The problem of distracting a car while zoom/scrolling the map. Actually it can not be achieved by adding an animation to annotation. I have found out the Interpolate function through which I can get the locations between "From" and "To" coordinates and set it to the annotation(setting annotation coordinate in milliseconds) will look like an animation.

It is not an issue of iOS or Map, if you are adding animation to annotation it will add to annotation layer not respect to the map point.

Disposition answered 9/10, 2013 at 9:29 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.