2016-05-31 18 views
1

Ich habe eine CALayer, die ich explizit auf eine neue Position animieren. Meine toValue Eigenschaft scheint nur relativ zur ursprünglichen Position der Ebene zu sein.Ist CABasicAnimation toValue relativ zur Anfangsposition?

CABasicAnimation *move = [CABasicAnimation animationWithKeyPath:@"position"]; 
    move.fromValue = [NSValue valueWithCGPoint:CGPointMake(blueDot.position.x, blueDot.position.y)]; 
    move.toValue = [NSValue valueWithCGPoint:CGPointMake(self.view.center.x, self.view.center.y)]; 
    move.duration = 1.0; 
    [blueDot addAnimation:move forKey:@"myMoveAnimation"]; 
    blueDot.position = CGPointMake(self.view.center.x, self.view.center.y); 

Dieser Code zeichnet die Ebene nicht in der Mitte der Ansicht neu. Es sieht so aus, als ob die Ebene wirklich auf CGPointMake(self.view.center.x + blueDot.position.x, self.view.center.y + blueDot.position.y) neu gezeichnet wird, so wie es die float Werte von self.view.center zu der Startposition der Ebene hinzufügt.

Soll die toValue Eigenschaft so handeln? Was ist der sauberste Weg, um meine blueDot in die Mitte der Ansicht zu bewegen?


EDIT:

-(void)viewDidLoad { 
     [super viewDidLoad]; 

     blueDot = [CAShapeLayer layer]; 
     [blueDot setPath:[[UIBezierPath bezierPathWithOvalInRect:CGRectMake(self.view.center.x - 60 - 5, 163.5, 10, 10)] CGPath]]; 
     [blueDot setStrokeColor: [UIColor blueColor]CGColor]; 
     [blueDot setFillColor:[UIColor blueColor]CGColor]; 
     [[self.view layer] addSublayer:blueDot]; 
    } 

// 163.5 is a placeholder for another view's position value so it's more readable for you guys. 
+0

Es gibt eine CAPropertyAnimation-Eigenschaft, die das Steuerelement 'additive' steuert. Wenn Sie es nicht ändern, sollte es standardmäßig deaktiviert sein. – jtbandes

+0

Ja, ich setze die 'additive' Eigenschaft nicht. – chicobermuda

+2

Es scheint auch, dass dies alles mit impliziten Animationen gemacht werden könnte, wenn Sie nur die Position ändern möchten. – jtbandes

Antwort

5

Das Problem ist, dass Sie die frame der Schicht sich bewegen, aber der blaue Punkt path dieser CAShapeLayer hat innerhalb dieser Schicht des frame durch self.view.center.x - 60 - 5, 163.5 versetzt worden ist, die Koordinaten, die Sie angegeben haben, als Erstellen der path für diese CAShapeLayer. Wenn Sie also die position des Layers animieren, wird der blaue Punkt immer noch um diesen Betrag von diesem neuen position versetzt.

Die Lösung besteht darin, die path der CAShapeLayer in der oberen linken Ecke der Schicht, z.

CAShapeLayer *blueDot = [CAShapeLayer layer]; 
blueDot.path = [UIBezierPath bezierPathWithArcCenter:CGPointMake(5, 5) radius:5 startAngle:0 endAngle:M_PI * 2 clockwise:true].CGPath; // note that using arc often generates a better looking circle, probably not noticeable at this size, just probably good practice 
blueDot.fillColor = [UIColor blueColor].CGColor; 

Nun, wenn Sie die position bewegen, das ist, wo die Herkunft des blauen Punkt bewegt.


Als Nebenwirkung würde ich eine separate UIView im Allgemeinen erstellen und diese CAShapeLayer dem hinzuzufügen. Auf diese Weise können Sie eine Vielzahl von verschiedenen Funktionen genießen:

  • können Sie genießen UIView Block-basierte Animation;
  • Sie können center verwenden Sie es, sich zu bewegen, so dass, wenn Sie seine center zum center seiner Super bewegen, wird es wirklich (jetzt zentriert werden, wenn Sie die position der Schicht zu self.view.center bewegen, es ist nicht wirklich ganz zentriert , da es die obere linke Ecke der Ebene des blauen Punktes ist, die in der Mitte sein wird);
  • Sie UIKit Dynamics verwenden können, um es zu Ort zu schnappen oder andere Verhaltensweisen zu definieren,
  • können Sie die automatische Layoutbeschränkungen verwenden Platzierung zu diktieren, wenn Sie wollen,
  • Sie eine UIView Unterklasse definieren könnte, die IBDesignable mit diesem Punkt ist als Ansicht, damit Sie sie auf einem Storyboard hinzufügen und sehen können, wie es aussieht; etc.
+0

Alternativ können Sie die Grenzen der Formebene als Begrenzungsbox für den Pfad festlegen. –

-1

Sie legen die toValue im Koordinatensystem des Super von view (wegen der Verwendung center Eigenschaft). Sieht aus wie das funktionieren sollte:

CABasicAnimation *move = [CABasicAnimation animationWithKeyPath:@"position"]; 
move.fromValue = [NSValue valueWithCGPoint:CGPointMake(blueDot.position.x, blueDot.position.y)]; 
move.toValue = [NSValue valueWithCGPoint:CGPointMake(CGRectGetMidX(view.bounds), CGRectGetMidY(view.bounds))]; 
move.duration = 1.0; 
[blueDot addAnimation:move forKey:@"myMoveAnimation"]; 
blueDot.position = CGPointMake(CGRectGetMidX(view.bounds), CGRectGetMidY(view.bounds)); 
+0

'CGRectGetMidX (self.view.bounds)' ist das selbe wie 'self.view.center.x'. Leider führt dies zum selben Ergebnis. – chicobermuda