2015-10-05 23 views
8

Ich schaffe es, einen CALayer entlang eines UIBezierPath zu animieren.Wie animiere ich nur einen Prozentsatz der vollständigen CALayer-Animation entlang eines UIBezierPfads?

Was ich versuche zu erreichen ist, nur einen Prozentsatz des Pfades zu animieren, zum Beispiel nur 25% des Pfades, wobei die Ebene an dieser Position bleibt (bei 25%).

Wie ist das möglich? Hier ist mein Code, es animiert immer den vollständigen Pfad.

let aPath = UIBizierPath(CGPath: somePath) 
let anim = CAKeyframeAnimation(keyPath: "position") 
anim.path = aPath.CGPath 
anim.rotationMode = kCAAnimationRotateAuto 
anim.repeatCount = 1 
anim.fillMode = kCAFillModeForwards 
anim.removedOnCompletion = false 
anim.duration = 3.0 
anim.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut) 

ticker.addAnimation(anim, forKey: "animate_ticker") 

Antwort

2

Einfache Änderung einer Eigenschaft:

anim.repeatCount = 0.25  

Hier ist ein excellent article on animation timing, können Sie lernen, wie man selbst haben, mehr feinkörnige Kontrolle über Ihre Animationen.

Anfügen:
1. Um zu erreichen, was Sie wollen, ist der nächste Weg, einen 25% subPath zu haben, hier ist ein paar helper method.

2. Wenn Sie die Geschwindigkeitsdifferenz stehen, Verwenden Sie die Methode oben, und legen Sie die Position zurück, wenn Animation endet:

ticker.position = ticker.presentationLayer().position 
+1

Das Problem dabei ist, dass die Animation nicht ein Viertel des Weges durch den * Pfad * stoppt, nur 1/4 des Weges durch die * Animation *. Mit einer 'kCAMediaTimingFunctionEaseInEaseOut'-Timing-Funktion und 0,25 für' repeatCount' stoppt die Animation früher als erwartet. Außerdem wird die Timing-Funktion immer noch auf die gesamte Dauer der Animation angewendet - und daher scheint sie schneller zu werden und dann plötzlich zu stoppen, was OP sein kann oder auch nicht. – Hamish

+0

@ originaluser2, Sie sind richtig. Ich fand die Animation nicht perfekt, wo ich dachte, das würde es tun, also erklärt es das! Vielen Dank! Ich suche nach 1/4 des Pfades, nicht nach der Animation. –

0

Versuchen Sie fromValue und toValue Eigenschaften festlegen? Es sollte funktionieren, wenn Sie fromValue zu 0,0 und toValue gesetzt zu 0,25

+1

'fromValue' und' toValue' werden in 'CABasicAnimation' eingeführt, das ist keine Oberklasse von' CAKeyframeAnimation' –

0

Nicht nur CGPath ist undurchsichtig, aber auch CAAnimation unterstützt kein Updates oder Benachrichtigungen für die laufenden Animationen (dh nach dem Start aber bevor fertig). Die einzigen beteiligten Entitäten sind die Animation selbst und CALayer -s, auf die es angewendet wird.

So Optionen sind:

(einige Optionen zu gruselig klingen, aber sie sind es nicht, so habe ich ein Beispielprojekt, siehe unten)

repeat

Wie wj2061 ist erwähnt his answer Sie kann Animation repeatCount zwicken. Cons ist es 0,25 Animationszeit animieren wird, nicht 0,25 Pfad

CAShapeLayer

Wenn durch Zufall, können Sie Ihre ticker mit CAShapeLayer Segment, dann können Sie animieren strokeStart und strokeEnd so wird es wie Segment aussehen entlang des Weges ist

bewegt

Clever repeat

Sie können solche repeatCount Wert berechnen, dass Animation bei 0,25 Pfad zu stoppen.

  • greifen einige Bezier-lib
  • Extrakt Bezier aus Timing-Funktion mit getControlPointAtIndex:
  • lösen Bezier seine „Fortschrittswert“ zu erhalten (in der Regel t genannt), für die der Bezier ‚y‘ den Wert Ihrer „erforderlich übereinstimmen Fortschritt“(0,25)
  • berechnen des Bezier 'x' Wert für diese t - das ist genau Wert von repeatCount Sie benötigen

Anim Ating mit CAAnimation, ganz alleine

Art vorgerückter

  • greifen einige Bezier-lib
  • benutzerdefinierte CALayer Unterklasse mit dynamischen Eigenschaft erstellen, lassen Sie uns rideProgress
  • Add synthetisierten Eigenschaften für Bezierpfad sagen (von Bezier lib, nicht CGPath) und Sublayer (zB rideLayer) zu animieren
  • überschreiben needsDisplayForKey: für rideProgress Schlüssel und initWithLayer: für alle eingeführten Eigenschaften ABER verwenden Sie self.rideLayer?.presentationLayer() anstelle von rideLayer
  • überschreiben Sie eine dieser: drawInContext: und zeichnen Sie, was Sie darin brauchen; Oder (besser) display, in display aktuellen Wert rideProgress Wert von abrufen und Sublayer aktualisieren, dann rufen Sie super. So oder so, verwendet Bezier lib Position und Rotation für Unterschicht zu aktuellem rideProgress Wert
  • nicht vergessen CATransaction.setDisableActions(true) entsprechend zu berechnen, bevor sie eine animierbaren Eigenschaft jeder Schicht
  • schließlich Einstellung, verwenden Sie jede Art von CAAnimation oder impliziter Animation auf rideProgress Immobilien

Split Weg

Wieder von wj2061 vorgeschlagen. Sie können den Pfad so eine der Hälften geteilt 0,25 Original


Here ist Beispielimplementierung alles über AUSSER „Split Pfad“ vertreten wird. Ich habe keine Feldtests mit diesem Code durchgeführt, es ist nur ein funktionierendes Konzept. XCode 7.3.1, Schnell.


Verwendete Materialien: Wiki on Cubic function, Great article about operations on beziers, Cubic equations solving method line-by-line

0

ich in der gleichen Ausgabe lief, und ich wollte die Zeichnung eines Pfad animieren, sondern nur einen Prozentsatz davon.

Was ich am Ende getan habe, war die StrokeStart und StrokeEnd Layer auf die gleichen Fließkommawerte wie die Animation.

Also versuchen Sie in Ihrem Beispiel anim.fromValue = 0.0f, anim.toValue = 0.6f und auch ticker.strokeStart=0.0f und ticker.strokeEnd = 0.6f.

Dies zog nur 60% des Pfades und animierte es auch!

+0

Ich kann mich nicht an die genauen Gründe erinnern, aber das hat nicht funktioniert. (Ich bin nicht derjenige, der die Meinung verlor) –