CABasicAnimation animiert meine Eigenschaft nicht

7

Ich habe versucht zu verstehen, was mit meiner Animation nicht stimmt und ich habe es immer noch nicht herausgefunden. Ich denke, es sollte wirklich geradlinig sein, aber es gibt wahrscheinlich etwas, was mir fehlt, selbst nachdem ich viele Beispiele und Dokumentationen gelesen habe.

Mein Problem kommt ursprünglich aus der Tatsache, dass Sie auf dem iPhone die Größe der Ebenen nicht automatisch ändern können (mit der Ansicht). Die Dokumentation sagt etwas anderes, aber es gibt keine autoresizeMask für den Layer in den SDKs. Also entschied ich mich, eine kleine Umgehungslösung zu erstellen und die Ebene selbst zu animieren.

Ich habe diesen einfachen Code, der eine einfache Größenanimation ausführen soll. Die Werte sind gut und ich setze sogar den Delegaten, um zu verfolgen, ob die Animation startet / endet.

%Vor%

Also, irgendwelche Ideen? (Diese Sicht, die den Code enthält, ist die Unteransicht einer Unteransicht des Fensters, wenn dies einen Unterschied machen könnte)

--- BEARBEITEN ---

Es scheint, dass der Rahmen nicht über CABasicAnimation und die benannte Eigenschaft "frame" animierbar ist. Wenn ich Grenzen verwende, habe ich ein seltsames Ergebnis, aber zumindest bekomme ich etwas. Wir werden weiter nachforschen.

    
Sauleil 19.07.2010, 19:30
quelle

3 Antworten

26

Es ist also gut, dass Sie hier etwas herausgefunden haben, aber Ihre Antwort auf Ihre eigene Frage hat einige Ungenauigkeiten. Lassen Sie mich ein paar Dinge korrigieren:

Die Rahmeneigenschaft kann animiert werden - nur nicht mit expliziter Animation. Wenn Sie für einen anderen Layer als den Root-Layer einer Ansicht Folgendes tun, wird der Rahmen sehr gut animiert:

%Vor%

Denken Sie daran, dass das Festlegen einer Eigenschaft auf einer Ebene diese Eigenschaftsänderung standardmäßig animiert. In der Tat müssen Sie Animationen bei einer Änderung der Eigenschaften deaktivieren, wenn Sie nicht animieren möchten. (Dies ist natürlich nur dann der Fall, wenn Sie eine andere Ebene als die Grundebene einer Ansicht animieren.) Wenn Sie eine explizite Animation verwenden müssen, stimmen Sie sowohl die Position als auch die Grenzen korrekt.

Sie können den Frame in einer UIView mit impliziter Animation animieren:

%Vor%

Dies wird aus dem aktuellen Frame (Grenzen und Position) der Ansicht zu x = 45.0, y = 45.0, w = 100.0, h = 100.0 animiert.

Es scheint, dass Sie auch den Unterschied zwischen einer Animation und einer Ebene falsch verstehen. Sie fügen Animationen zu Ebenen hinzu, aber das Hinzufügen einer Animation zu einer Ebene legt die Eigenschaft, die Sie animieren, nicht automatisch fest.

CALayers sind Modellobjekte. Sie enthalten Informationen über die Ebene, die schließlich auf dem Bildschirm gerendert wird. Sie müssen die Eigenschaft eines Layers festlegen, wenn diese Eigenschaft diesen Wert haben soll. Wenn Sie die Eigenschaft einfach animieren, handelt es sich nur um eine visuelle Darstellung und nicht um eine tatsächliche Darstellung. Aus diesem Grund springt der Wert auf den ursprünglichen Wert der Ebene zurück, da Sie ihn nie wirklich geändert haben.

Was mich zum nächsten Punkt führt. Du hast gesagt:

  

Verwenden Sie "animation.removedOnCompletion =   NEIN; animation.fillMode =   kCAFillModeForwards; "um sicherzustellen, dass   Die Werte werden am Ende nicht zurückgesetzt   der Animation

Das ist nicht genau richtig. Diese beiden Werte bewirken lediglich, dass die Animation an ihrer endgültigen Position visuell bleibt, die tatsächlichen Werte der Ebene haben sich jedoch nicht geändert. Sie sind immer noch die gleichen Werte wie beim Start der Animation. Im Allgemeinen (mit einigen Ausnahmen) möchten Sie diese beiden Parameter nicht verwenden, da sie nur visuell sind. Sie möchten den Ebenenwert für die zu animierende Eigenschaft tatsächlich festlegen.

Sagen Sie zum Beispiel, dass Sie die Position Ihrer Ebene mit einer expliziten Animation animieren möchten. Hier ist der Code, den Sie wollen:

%Vor%

Sie sollten auch die Gruppierung von Animationen berücksichtigen. Mit einer Animationsgruppe können Sie mehrere Animationen zusammen gruppieren und dann steuern, wie sie miteinander in Beziehung stehen. In deinem Fall ist die Dauer für deine Grenzen und Positionsanimationen die gleiche und was du versuchst zu tun, wird ohne eine Gruppe gut funktionieren, aber wenn du den Beginn der Animationen ausgleichen möchtest, zum Beispiel wollte du die Position nicht Animation, um bis ein oder zwei Sekunden in die Frame-Animation zu starten, können Sie sie versetzen, indem Sie den Wert beginTime der Positionsanimation festlegen.

Schließlich wäre ich neugierig, warum Sie die im UIView verfügbaren impliziten Animationen nicht verwenden könnten. Ich benutze diese in der überwiegenden Mehrheit der Core Animation Code ich kann nicht sehen, warum dies für Ihre Situation nicht funktionieren würde.

Beste Grüße.

    
Matt Long 20.07.2010, 16:45
quelle
3

Der Schlüsselpfad sollte nur der Schlüsselpfad der Eigenschaft sein, nicht der Name des Objekts.

Benutze dies

%Vor%

statt dessen

%Vor%

Und nur wenn Sie einer Ebene Animation hinzufügen, bedeutet der Schlüssel nicht die zu animierende Schlüsseleigenschaft. Nur der Schlüssel (Name), den diese Animation haben soll (bezieht sich auf die letzte Zeile Ihres Codes)

    
tadejsv 19.07.2010 19:34
quelle
1

Die Lösung bestand also darin, die @ "Grenzen" und die @ "Position" der Ebene zu animieren, da der Rahmen auf dem iPhone nicht animierbar ist. Ich brauchte einige Zeit, um zu verstehen, dass die Position das Zentrum der Ebene war und die Größenänderung der Grenzen sich von der Mitte aus erstreckte, aber das war der einfache Teil.

Also, was ich im Lebenslauf getan habe, war:

  1. Erstellen Sie im setFrame 2 Animationen mit den Eigenschaften bounds und position.
  2. Verwenden Sie "animation.removedOnCompletion = NO; animation.fillMode = kCAFillModeForwards;" um sicherzustellen, dass die Werte nicht am Ende der Animation zurückgesetzt werden
  3. Registrieren Sie den Delegaten bei sich selbst, um "animationDidStop: finished:" zu implementieren. Anscheinend müssen Sie die Werte noch festlegen: "layerImage.bounds = [animation.toValue CGRectValue]; layerImage.position = [animation.toValue CGPointValue];".

Ich konnte das UIView-Animationssystem nicht direkt verwenden, weil es auf den Ebenen nicht die gewünschten Funktionen hatte.

Danke tadej5553, dass ich auf das Layer-Problem mit der "addAnimation" hingewiesen habe. Also hier ist der Code für diejenigen, die sehen möchten, wie es aussieht.

%Vor%     
Sauleil 20.07.2010 14:12
quelle