Définissez repeatcount sur 1 et rajoutez l'animation après chaque animation arrêtée. Je ne suis pas sûr si cela cause problème de performance dans votre scénario depuis que je l'ai testé avec une vue carrée très basique.
En ajoutant un paramètre CAMediaTimingFunction
, vous êtes en mesure de contrôler si vous souhaitez utiliser kCAMediaTimingFunctionLinear
- pour les boucles d'animation normales, ou d'utiliser un personnalisé, comme kCAMediaTimingFunctionEaseIn
- pour l'image clé d'animation pour montrer une transition en douceur .
// your function to start the acceleration
@IBAction func buttonTapped(_ sender: UIButton) {
accel = true
speed = 2.0
timeOffset = self.rect.layer.convertTime(CACurrentMediaTime(), from: nil)
timeOffset = timeOffset - lastStart
// memorize the timeoffset, new speed (2x) and a boolean flag
self.rect.layer.removeAllAnimations()
}
// delegate - memorize the CFTimeInterval
func animationDidStart(_ anim: CAAnimation) {
lastStart = self.rect.layer.convertTime(CACurrentMediaTime(), from: nil)
}
// delegate - start a new loop of animation each time it's stopped
func animationDidStop(_ anim: CAAnimation, finished flag: Bool) {
if accel {
accel = false
let opt = CAMediaTimingFunction(controlPoints: 0.5, 0.2, 0.9, 0.7)
rotateAnimation(theView: rect, speed: speed, fromValue: CGFloat(.pi * 2.0 * Float(timeOffset)/10.0), toValue: CGFloat(.pi * 2.0 * Float(timeOffset)/10.0 + .pi * 2.0), option: opt)
} else {
rotateAnimation(theView: rect, speed: speed, fromValue: CGFloat(.pi * 2.0 * Float(timeOffset)/10.0), toValue: CGFloat(.pi * 2.0 * Float(timeOffset)/10.0 + .pi * 2.0))
// note that timeOffset is initialize to be 0.
}
}
Vous voulez un CAMediaTimingFunction personnalisé ici, commencez par une pente de 0,5 et augmenter progressivement à 1,0, je ne l'ai pas optimiser la courbe de Bézier ici, vous pouvez faire votre propre courbe souhaitée.
Enfin un peu tweak à votre fonction d'animation:
func rotateAnimation(theView: UIView, speed: Float, duration: CFTimeInterval = 10.0, fromValue: CGFloat = CGFloat(0.0), toValue: CGFloat = CGFloat(.pi * 2.0), option: CAMediaTimingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionLinear)) {
let rotateAnimation = CABasicAnimation(keyPath: "transform.rotation")
rotateAnimation.fromValue = fromValue
rotateAnimation.toValue = toValue
rotateAnimation.duration = duration
rotateAnimation.speed = speed
rotateAnimation.repeatCount = 1
rotateAnimation.delegate = self
rotateAnimation.timingFunction = option
theView.layer.add(rotateAnimation, forKey: nil)
}
ne changeant l'aide de la durée? – 3stud1ant3
@ 3stud1ant3 Non, cela change la vitesse mais après quelques secondes, l'animation revient à sa vitesse d'origine. – NoKey
Sur la même note que la modification de la durée, avez-vous essayé une boucle while avec la ligne de condition spécifiant la position finale de l'animation? – ProgrammingEnthusiast