CAShapeLayer Animation

Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

  • CAShapeLayer Animation

    Hi,

    ich bin am verzweifeln. Ich hab mir einen Shape Layer und diesen will ich animiert zeichnen. Soweit so gut. Ich hab auch Code geschrieben, damit dies funktioniert. Nur der Haken ist, dass der Kreis schon vor der Animation gezeichnet wird und dann noch mal gezeichnet wird. Das sieht blöd aus. Wie kann man das verhindern, dass er beim starten gezeichnet wird und ihn erst bei der Animation Zeichnen?


    Quellcode

    1. CAShapeLayer *progressLayerRed = [[CAShapeLayer alloc] init];
    2. [progressLayerRed setPath:circleTimeRed.CGPath];
    3. [progressLayerRed setStrokeColor:[UIColor blackColor].CGColor];
    4. [progressLayerRed setFillColor:[UIColor clearColor].CGColor];
    5. [progressLayerRed setLineWidth:5.0f];
    6. [progressLayerRed setStrokeStart:0.0];
    7. [progressLayerRed setStrokeEnd:1.0];
    8. [self.layer addSublayer:progressLayerRed];
    9. [CATransaction begin];
    10. CABasicAnimation *animateStrokeEndOtherColors = [CABasicAnimation animationWithKeyPath:@"strokeEnd"];
    11. animateStrokeEndOtherColors.duration = self.timePerCircle;
    12. animateStrokeEndOtherColors.fromValue = [NSNumber numberWithFloat:0.0f];
    13. animateStrokeEndOtherColors.toValue = [NSNumber numberWithFloat:1.0f];
    14. animateStrokeEndOtherColors.fillMode = kCAFillModeBoth;
    15. animateStrokeEndOtherColors.removedOnCompletion = NO;
    16. [CATransaction setCompletionBlock:^{
    17. [CATransaction setCompletionBlock:^{
    18. [progressLayerRed addAnimation:animateStrokeEndOtherColors forKey:nil];
    19. }];
    20. ....
    Alles anzeigen

    Ich möchte ein ganzen Kreis animiert Zeichen und den in verschieden Farben. Zurzeit mache ich das mit verschieden Kreisen, da es von Grün zu Gelb und da zu Rot gehen soll. Geht das auch nur mit einen Kreis? Denn irgendwie bin ich mit meiner Lösung nicht zufrieden. Das muss doch eleganter gehen so ein Timer.

    Viele Grüße und Vielen Dank im voraus!
    Nils
  • Einen Layer in einem Runloop-Zyklus hinzufügen und animieren ist, soweit ich mich recht erinnere, nicht möglich. Du solltest den Layer lieber vorher schon mit strokeEnd = 0 hinzufügen. Anstelle des Completion-Blocks solltest du auch lieber das Delegate der Animation verwenden. Deine Transaktion macht so keinen Sinn.

    Für die Animation dann im Layer strokeEnd = 1.0 setzen und in der Animation den fromValue auf 0. Den toValue brauchst du dann nicht in der Animation setzen.
    „Meine Komplikation hatte eine Komplikation.“
  • macmoonshine schrieb:

    Einen Layer in einem Runloop-Zyklus hinzufügen und animieren ist, soweit ich mich recht erinnere, nicht möglich. Du solltest den Layer lieber vorher schon mit strokeEnd = 0 hinzufügen. Anstelle des Completion-Blocks solltest du auch lieber das Delegate der Animation verwenden. Deine Transaktion macht so keinen Sinn.


    Für die Animation dann im Layer strokeEnd = 1.0 setzen und in der Animation den fromValue auf 0. Den toValue brauchst du dann nicht in der Animation setzen.
    Vielen Dank! Das probiere ich!

    MCDan schrieb:

    Lasse mal setStrokeStart und setStrokeEnd weg.
    Das bringt leider nichts.
  • Hier mal ein Code Schnipsel, welcher bei mir problemlos funktioniert:

    Quellcode

    1. CAShapeLayer *shapeLayer = [CAShapeLayer layer];
    2. shapeLayer.path = path.CGPath;
    3. shapeLayer.strokeColor = color.CGColor;
    4. shapeLayer.fillColor = nil;
    5. shapeLayer.lineWidth = 1.5;
    6. shapeLayer.lineJoin = kCALineJoinRound;
    7. shapeLayer.lineDashPattern = dashPattern;
    8. [self.layer addSublayer:shapeLayer];
    9. CABasicAnimation *pathAnimation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"];
    10. pathAnimation.duration = duration;
    11. pathAnimation.fromValue = @(0.0f);
    12. pathAnimation.toValue = @(1.0f);
    13. pathAnimation.removedOnCompletion = YES;
    14. [shapeLayer addAnimation:pathAnimation forKey:@"pathAnimation"];
    Alles anzeigen
  • Sorry, dass ich mich so lange nicht gemeldet habe aber ich kam nicht dazu. Also mit den Varianten von @markusschalk und @MCDan geht es nicht. Selber Effekt wie bei meinen Code. Ich hab mal ein Beispiel Projekt gemacht. Vlt. sieht da je jemand den Fehler. der Gelbe und Schwarze Kreis sind schon da, obwohl sie noch gar nicht da sein sollten.

    @macmoonshine: Was meinst du mit Delegate Methoden? Das finde ich irgendwie umständlicher da ich da ja unterscheiden muss welchen View ich jetzt animiere oder verstehe ich da was Falsch?
    Dateien
    • Circle Test.zip

      (31,86 kB, 108 mal heruntergeladen, zuletzt: )
  • AppleDeveloper schrieb:

    Was meinst du mit Delegate Methoden?
    Du kannst natürlich auch den Completion-Block der Transaktion oder den Completion-Block der UIView-Animationsmethoden verwenden. Nur so wie du den Transaktion verwendest, macht das keinen Sinn. Der Completion-Block der Transaktion wird natürlich an deren Ende ausgeführt, was aber nicht unbedingt das Ende der Animation sein muss.

    Für die Implementierung von animationDidStop:finished: gibt es elegante Möglichkeiten.
    „Meine Komplikation hatte eine Komplikation.“
  • macmoonshine schrieb:

    AppleDeveloper schrieb:

    Was meinst du mit Delegate Methoden?
    Du kannst natürlich auch den Completion-Block der Transaktion oder den Completion-Block der UIView-Animationsmethoden verwenden. Nur so wie du den Transaktion verwendest, macht das keinen Sinn. Der Completion-Block der Transaktion wird natürlich an deren Ende ausgeführt, was aber nicht unbedingt das Ende der Animation sein muss.


    Für die Implementierung von animationDidStop:finished: gibt es elegante Möglichkeiten.
    Danke! Das teste ich mal!
  • Also in der drawRect Methode machen CAShapeLayer eigentlich überhaupt keinen Sinn. CAShapeLayer ist ja eigener CALayer mit einer eigenen drawRect bzw. drawInContext: Methode.

    Wenn Du quasi 3 CAShapeLayer aufeinanderfolgend zeichnen möchtest, dann darfst Du den nachfolgenden Layer natürlich erst per addSublayer: hinzufügen, wenn die Animation des vorherigen CAShapeLayer abgeschlossen ist (startAnimation). Alternativ musst Du den strokeEnd der CAShapeLayer mit 0 initialisieren, da der CAShapeLayer seinen Path nach dem Hinzufügen sonst schon bis zum Ende anzeigt (startAnimationAlternativ). ;)

    Anbei das geänderte Projekt.
    Dateien
  • MCDan schrieb:

    Also in der drawRect Methode machen CAShapeLayer eigentlich überhaupt keinen Sinn. CAShapeLayer ist ja eigener CALayer mit einer eigenen drawRect bzw. drawInContext: Methode.


    Wenn Du quasi 3 CAShapeLayer aufeinanderfolgend zeichnen möchtest, dann darfst Du den nachfolgenden Layer natürlich erst per addSublayer: hinzufügen, wenn die Animation des vorherigen CAShapeLayer abgeschlossen ist (startAnimation). Alternativ musst Du den strokeEnd der CAShapeLayer mit 0 initialisieren, da der CAShapeLayer seinen Path nach dem Hinzufügen sonst schon bis zum Ende anzeigt (startAnimationAlternativ). ;)

    Anbei das geänderte Projekt.
    Wow!! Dankeschön!! Da war ich ja komplett falsch! Da hab ich ja komplett falsch gedacht! Vielen Vielen Dank! Das ist ja so ähnlich wie @macmoonshine gesagt hat! Danke dir!! Danken alle für die Hilfe!!