2017-08-26 11 views
3

ich diesen Code jede Ansicht drehen aufbrauchen:beschleunigen Reibungslos eine Laufdreh Animation

func rotateAnimation(theView: UIView, duration: CFTimeInterval = 20.0, repeatCount: Float = 200, toValue: CGFloat = CGFloat(.pi * 2.0)) { 
    let rotateAnimation = CABasicAnimation(keyPath: "transform.rotation") 
    rotateAnimation.fromValue = 0.0 
    rotateAnimation.toValue = toValue 
    rotateAnimation.duration = duration 
    rotateAnimation.repeatCount = repeatCount 
    theView.layer.add(rotateAnimation, forKey: nil) 
} 

Ich würde gerne wissen, wie zu beschleunigen, dass derzeit Animation läuft. Wenn zum Beispiel eine UIView mit dem obigen Code rotiert, wie kann ich diese Geschwindigkeit mit einer schönen Transation doppelt so schnell machen?

Also: ruft rotateAnimation: bei normaler Geschwindigkeit rotiert ->Anrufe Funktion? -> UIView wird reibungslos schneller auf die gewünschte Geschwindigkeit drehen -> UIView dreht weiter mit der gewünschten Geschwindigkeit.

Danke für jede Hilfe.

+0

hat die Änderung der Dauer Hilfe? – 3stud1ant3

+0

@ 3stud1ant3 Nein, es ändert die Geschwindigkeit, aber nach ein paar Sekunden ist die Animation wieder auf ihre ursprüngliche Geschwindigkeit. – NoKey

+0

Haben Sie zur Änderung der Dauer auch eine while-Schleife mit der Bedingungszeile versucht, die die endgültige Position der Animation angibt? – ProgrammingEnthusiast

Antwort

2

Bitte versuchen Sie es Below-Code

 let timer = Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true) { (timer) in 
      self.viewToMove.layer.timeOffset = self.viewToMove.layer.convertTime(CACurrentMediaTime(), from: nil) 
      self.viewToMove.layer.beginTime = CACurrentMediaTime() 
      self.viewToMove.layer.speed += 0.5 

     } 
     timer.fire() 

Es wird sehr glatt Animationsgeschwindigkeit erhöhen

+0

Ja danke, es funktioniert mit ein paar Zeilen Code :) –

0

Versuchen Sie, diese für die zweite Animation

können Sie kleinere Dauer eingestellte Geschwindigkeit zu erhöhen

func rotateAnimation(theView: UIView, duration: CFTimeInterval = 0.4, repeatCount: Float = 200, toValue: CGFloat = CGFloat(.pi * 2.0)) { 
    let rotateAnimation = CABasicAnimation(keyPath: "transform.rotation") 
    rotateAnimation.fromValue = 0.0 
    rotateAnimation.toValue = toValue 
    rotateAnimation.duration = duration 
    rotateAnimation.repeatCount = repeatCount 

Und gesetzt shouldRasterize = true für eine bessere Leistung

theView.layer.rasterizationScale = UIScreen.main.scale 
    theView.layer.shouldRasterize = true 

Verwenden den gleichen Schlüssel für beide Animationen

theView.layer.add(rotateAnimation, forKey: "animation") 
} 
0

Setzen Sie repeatcount auf 1 und fügen Sie die Animation nach jeder angehaltenen Animation erneut hinzu. Ich bin mir nicht sicher, ob dies in Ihrem Szenario zu Performance-Problemen führt, da ich es mit einer sehr einfachen quadratischen Ansicht getestet habe.

Durch das Hinzufügen eines CAMediaTimingFunction Parameters, sind Sie in der Lage zu kontrollieren, ob kCAMediaTimingFunctionLinear verwenden - für die normale Animation Loops oder einen benutzerdefinierten ein, wie kCAMediaTimingFunctionEaseIn zu verwenden - für den Schlüssel Animationsrahmen um einen reibungslosen Übergang zu zeigen, .

// 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. 
    } 
} 

Sie möchten eine benutzerdefinierte CAMediaTimingFunction hier, durch eine Steigung von 0,5 beginnen und allmählich auf 1,0 zu erhöhen, ich habe optimieren nicht die Bezier-Kurve hier, können Sie Ihre eigene gewünschte Kurve tun.

Endlich ein wenig zwicken, um Ihre Animation Funktion:

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) 
} 
Verwandte Themen