2016-07-25 42 views
8

Ich versuche, einen benutzerdefinierten Aktivitätsindikator vergleichbar mit dem Android-Materialentwurf kreisförmige unbestimmte Aktivität Indikator. Grundsätzlich möchte ich den Kreis zwei Mal zeichnen und löschen, aber Löschen und Zeichnen geschieht nicht zur gleichen Zeit oder Geschwindigkeit. Dies ist, was ich bisher habe:Verbinden Sie zwei strokeEnd Animationen

let progressLayer = CAShapeLayer() 
progressLayer.strokeColor = UIColor.red().cgColor 
progressLayer.fillColor = nil 
progressLayer.lineWidth = 2 

let drawAnimation = CABasicAnimation(keyPath: "strokeEnd") 
drawAnimation.duration = duration/2 
drawAnimation.fromValue = 0 
drawAnimation.toValue = 1 
drawAnimation.isRemovedOnCompletion = false 
drawAnimation.fillMode = kCAFillModeForwards 

let eraseAnimation = CABasicAnimation(keyPath: "strokeStart") 
eraseAnimation.duration = duration/2 
eraseAnimation.beginTime = 0.2 
eraseAnimation.fromValue = 0 
eraseAnimation.toValue = 0.4 
eraseAnimation.isRemovedOnCompletion = false 
eraseAnimation.fillMode = kCAFillModeForwards 

let endDrawAnimation = CABasicAnimation(keyPath: "strokeEnd") 
endDrawAnimation.beginTime = duration/2 
endDrawAnimation.duration = duration/2 
endDrawAnimation.fromValue = 0 
endDrawAnimation.toValue = 1 
endDrawAnimation.isRemovedOnCompletion = false 
endDrawAnimation.fillMode = kCAFillModeForwards 

let endEraseAnimation = CABasicAnimation(keyPath: "strokeStart") 
endEraseAnimation.beginTime = duration/2 
endEraseAnimation.duration = duration/4 
endEraseAnimation.fromValue = 0.4 
endEraseAnimation.toValue = 1 
endEraseAnimation.isRemovedOnCompletion = false 
endEraseAnimation.fillMode = kCAFillModeForwards 

let endEraseAnimation2 = CABasicAnimation(keyPath: "strokeStart") 
endEraseAnimation2.beginTime = duration * 3/4 
endEraseAnimation2.duration = duration/4 
endEraseAnimation2.fromValue = 0 
endEraseAnimation2.toValue = 1 
endEraseAnimation2.isRemovedOnCompletion = false 
endEraseAnimation2.fillMode = kCAFillModeForwards 


let animations = CAAnimationGroup() 
animations.duration = duration 
animations.animations = [drawAnimation, eraseAnimation, endDrawAnimation, endEraseAnimation, endEraseAnimation2] 
animations.isRemovedOnCompletion = false 
animations.fillMode = kCAFillModeForwards 
progressLayer.add(animations, forKey: "stroke") 

Der Code macht alles wie erwartet, mit Ausnahme eines Problems. Wenn die erste strokeEnd Animation gemacht wird und die zweite beginnt, gibt es eine Art Flash, was bedeutet, dass der Teil des Kreises, der bis zu diesem Punkt gezeichnet wurde, verschwindet und dann wieder von 0 beginnt. Hat jemand irgendwelche Ideen, wie das zu beheben ist?

+0

Ihr Code anzeigen Fehler, wenn ich zu kompilieren versuchen, bitte deinen Code setzen, um zu helfen Sie –

+0

@ReinierMelian das ist Swift 3 Code, stellen Sie sicher, dass Sie Xcode 8 verwenden oder es zu Swift 2 übersetzen. @Banana, was ist 'progressLayer'? – JAL

+0

'progressLayer' ist ein' CAShapeLayer', den ich der obigen Frage hinzugefügt habe. – Banana

Antwort

0

Wenn die erste strokeEnd Animation erfolgt und die zweite beginnt dort eine Art von Flash den Teil des Kreises bedeutet, dass bis zu diesem Punkt gezogen wurde, verschwindet, und dann beginnt wieder bei 0.

Zeichnung

Wenn Sie das Setup von drawAnimation und endDrawAnimation vergleichen, werden Sie sehen, dass sie bis auf die beginTime Eigenschaft identisch sind. Das verursacht dein Flackern. Sie beginnen beide bei 0 und beide Ende mit 1. Da Sie nicht das gewünschte Ergebnis angegeben Ich kann nur annehmen, dass Sie endDrawAnimation wollen Verbesserungs eine fromValue von 1.

let drawAnimation = CABasicAnimation(keyPath: "strokeEnd") 
drawAnimation.duration = duration/2 
drawAnimation.fromValue = 0 
drawAnimation.toValue = 1 
drawAnimation.isRemovedOnCompletion = false 
drawAnimation.fillMode = kCAFillModeForwards 

let endDrawAnimation = CABasicAnimation(keyPath: "strokeEnd") 
endDrawAnimation.beginTime = duration/2 // Starts after the first animation and starts with 0 again. 
endDrawAnimation.duration = duration/2 
endDrawAnimation.fromValue = 0 
endDrawAnimation.toValue = 1 
endDrawAnimation.isRemovedOnCompletion = false 
endDrawAnimation.fillMode = kCAFillModeForwards 

Anregung haben

Soweit ich sehen kann, möchten Sie Key Frame Animation erstellen, was bedeutet, dass Sie Offsets definiert haben, bei denen sich das Animationsverhalten (Geschwindigkeit, Wert, etc.) ändert. Vielleicht möchten Sie stattdessen CAKeyframeAnimation verwenden.

Ich bin nicht sicher, ob Sie sich dessen bewusst sind, aber im Moment haben Sie zwei Animationen gleichzeitig auf strokeStart ausgeführt wird:

  • eraseAnimation, die mit einer Dauer von 0.5 * duration
  • endEraseAnimation bei 0.2 beginnt, die bei 0.5 * duration beginnt .

Das bedeutet, dass das Ende der eraseAnimation (0.2 + 0.5 * duration) ist immer größer als der Beginn der endEraseAnimation (0.5 * duration)