25 votes

Voiture (Annotation) animation (comme l'application uber) ne fonctionne pas

J'ai réalisé un projet de démonstration (à partir du démo Moving-MKAnnotationView sur github) pour déplacer une voiture sur une carte. Voici le lien :

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

J'ai modifié mon code en me basant sur la réponse donnée par vinaut mais le problème persiste. Lorsque nous zoomons ou faisons défiler la carte, l'animation est perturbée sous iOS 7 et sous iOS 6, lorsque nous zoomons ou faisons défiler la carte, l'annotation se remet à son angle d'origine pendant un moment.

Voici une capture d'écran de mon projet de démonstration :

Description de l'image

Voici une partie du code que j'ai modifiée :

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

    //extraire le point de la carte à partir de cette structure bidon (enveloppe) CGPoint
    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;
}

Mon objectif est de déplacer la voiture de la même manière que dans l'application Uber.

14voto

vinaut Points 1873

Il semble que quelque chose a changé avec les fonctions de conversion pour CLCoordinate2D/MKMapPoint/CGPoint...

La détection d'un point dans un MKPolygon est cassée avec iOS7 (CGPathContainsPoint)

L'annotation disparaît car la conversion entre MkMapPoints et CGIPoints ne fonctionne plus, si vous enregistrez la "position" de la CALayer, vous obtiendrez des points bien en dehors de la vue. Aucune idée pourquoi cela fonctionne lors des événements tactiles.

Si vous modifiez la fonction comme suit :

    - (void) setPosition : (id) posValue; 
{
    //extrayez le mapPoint de cette structure bidon (wrapper) CGPoint
    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;

}

Cela devrait fonctionner à nouveau.

14voto

100grams Points 1185

Je suis le contributeur original de Moving-MKAnnotationView (https://github.com/100grams/Moving-MKAnnotationView.git). Ce composant a été initialement écrit pour iOS4.3 et beaucoup de choses ont changé depuis. :-)

La cause principale ici était la conversion de MKMapPoint en CGPoint (coordonnées de l'écran). Bien que le code fonctionnait avant, il ne fonctionne pas sur iOS7 et je l'ai corrigé en utilisant ceci pour convertir les coordonnées lat/lon en coordonnées d'écran:

convertCoordinate:toPointToView:

J'ai ajouté cette correction, avec quelques autres mises à jour, à https://github.com/100grams/Moving-MKAnnotationView.git donc il fonctionne maintenant sur iOS7/Xcode5.

1voto

Le problème de détourner l'attention d'une voiture tout en zoomant / faisant défiler la carte. En fait, cela ne peut pas être réalisé en ajoutant une animation à une annotation. J'ai découvert la fonction Interpolate grâce à laquelle je peux obtenir les emplacements entre les coordonnées "De" et "À" et les définir pour l'annotation (définir la coordonnée de l'annotation en millisecondes) ressemblera à une animation.

Ce n'est pas un problème d'iOS ou de Map, si vous ajoutez une animation à une annotation, elle sera ajoutée à la couche d'annotation et non au point de la carte.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X