Ich drehe einen CALayer und versuche, ihn nach Abschluss der Animation an seiner endgültigen Position anzuhalten.
Nach Abschluss der Animation wird sie jedoch auf ihre ursprüngliche Position zurückgesetzt.
(In xcode-Dokumenten wird ausdrücklich angegeben, dass die Animation den Wert der Eigenschaft nicht aktualisiert.)
Vorschläge, wie dies erreicht werden kann.
ios
iphone
calayer
cabasicanimation
Nilesh Ukey
quelle
quelle
.presentation()
den "endgültigen, gesehenen" Wert an. Suchen Sie nach den richtigen Antworten, die erklären, wie es mit der Präsentationsebene gemacht wird.Antworten:
Hier ist die Antwort, es ist eine Kombination aus meiner Antwort und Krishnans.
Der Standardwert ist
kCAFillModeRemoved
. (Welches ist das Reset-Verhalten, das Sie sehen.)quelle
Das Problem mit removeOnCompletion ist, dass das UI-Element keine Benutzerinteraktion zulässt.
Die Technik besteht darin, den FROM-Wert in der Animation und den TO-Wert für das Objekt festzulegen. Die Animation füllt den TO-Wert automatisch, bevor sie gestartet wird. Wenn sie entfernt wird, bleibt das Objekt im richtigen Zustand.
quelle
alphaAnimation.beginTime = 1;
Auch dasfillMode
wird nicht benötigt, soweit ich das beurteilen kann ...?beginTime
nicht relativ ist, sollten Sie zB verwenden:CACurrentMediaTime()+1;
fillMode
. Weitere Informationen findenLegen Sie die folgende Eigenschaft fest:
quelle
Fügen Sie es einfach in Ihren Code ein
quelle
Sie können den Schlüssel einfach auf setzen
CABasicAnimation
,position
wenn Sie ihn der Ebene hinzufügen. Auf diese Weise wird die implizite Animation überschrieben, die an der Position für den aktuellen Durchlauf in der Ausführungsschleife ausgeführt wird.Weitere Informationen zu Apple WWDC Video Session 421 2011 - Core Animation Essentials (Mitte des Videos) finden Sie hier.
quelle
someLayer.position = endPosition;
. Und danke für den Hinweis an die WWDC!Eine CALayer hat eine Modellebene und eine Präsentationsebene. Während einer Animation wird die Präsentationsebene unabhängig vom Modell aktualisiert. Wenn die Animation abgeschlossen ist, wird die Präsentationsebene mit dem Wert aus dem Modell aktualisiert. Wenn Sie nach dem Ende der Animation einen Störsprung vermeiden möchten, müssen Sie die beiden Ebenen synchron halten.
Wenn Sie den Endwert kennen, können Sie das Modell einfach direkt einstellen.
Wenn Sie jedoch eine Animation haben, bei der Sie die Endposition nicht kennen (z. B. eine langsame Überblendung, die der Benutzer anhalten und dann umkehren kann), können Sie die Präsentationsebene direkt abfragen, um den aktuellen Wert zu ermitteln, und dann das Modell aktualisieren.
Das Abrufen des Werts aus der Präsentationsebene ist auch besonders nützlich für Skalierungs- oder Rotationsschlüsselpfade. (z
transform.scale
,transform.rotation
)quelle
Ohne die
removedOnCompletion
Sie können diese Technik ausprobieren:
quelle
Mein Problem war also, dass ich versuchte, ein Objekt mit einer Schwenkgeste zu drehen, und dass ich bei jeder Bewegung mehrere identische Animationen hatte. Ich hatte beides
fillMode = kCAFillModeForwards
undisRemovedOnCompletion = false
aber es hat nicht geholfen. In meinem Fall musste ich sicherstellen, dass der Animationsschlüssel jedes Mal anders ist, wenn ich eine neue Animation hinzufüge :quelle
Einfach einstellen
fillMode
undremovedOnCompletion
bei mir nicht funktioniert. Ich habe das Problem gelöst, indem ich alle folgenden Eigenschaften auf das CABasicAnimation-Objekt festgelegt habe:Dieser Code wird
myView
in 85% seiner Größe umgewandelt (3. Dimension unverändert).quelle
Die Kernanimation verwaltet zwei Ebenenhierarchien: die Modellebene und die Präsentationsebene . Während der Animation ist die Modellebene tatsächlich intakt und behält ihren Anfangswert bei. Standardmäßig wird die Animation nach Abschluss entfernt. Dann fällt die Präsentationsschicht auf den Wert der Modellebene zurück.
Einfach einstellen
removedOnCompletion
aufNO
wird die Animation nicht entfernt und Speicherplatz verschwendet. Außerdem sind die Modellebene und die Präsentationsschicht nicht mehr synchron, was zu potenziellen Fehlern führen kann.Daher wäre es eine bessere Lösung, die Eigenschaft direkt auf der Modellebene auf den Endwert zu aktualisieren.
Wenn durch die erste Zeile des obigen Codes implizite Animationen verursacht werden, versuchen Sie, diese zu deaktivieren, wenn:
quelle
Das funktioniert:
Die Kernanimation zeigt während der Animation eine Präsentationsebene auf Ihrer normalen Ebene. Stellen Sie die Deckkraft (oder was auch immer) auf das ein, was Sie sehen möchten, wenn die Animation beendet ist und die Präsentationsebene verschwindet. Führen Sie dies in der Zeile aus, bevor Sie die Animation hinzufügen, um ein Flackern nach Abschluss zu vermeiden.
Wenn Sie eine Verzögerung wünschen, gehen Sie wie folgt vor:
Wenn Sie schließlich 'removeOnCompletion = false' verwenden, werden CAAnimations durchgesickert, bis die Ebene schließlich entsorgt wird - vermeiden Sie dies.
quelle
@Leslie Godwins Antwort ist nicht wirklich gut, "self.view.layer.opacity = 1;" Wenn dies sofort erledigt ist (es dauert ungefähr eine Sekunde), korrigieren Sie alphaAnimation.duration auf 10.0, wenn Sie Zweifel haben. Sie müssen diese Zeile entfernen.
Wenn Sie also fillMode auf kCAFillModeForwards korrigieren undOnCompletion auf NO entfernen, bleibt die Animation in der Ebene. Wenn Sie den Animationsdelegierten reparieren und Folgendes versuchen:
... die Ebene wird sofort wiederhergestellt, sobald Sie diese Zeile ausführen. Das wollten wir vermeiden.
Sie müssen die Ebeneneigenschaft korrigieren, bevor Sie die Animation daraus entfernen. Versuche dies:
quelle
Es scheint, dass das Flag "RemoveOnCompletion" auf "false" und "fillMode" auf "kCAFillModeForwards" gesetzt ist.
Nachdem ich eine neue Animation auf eine Ebene angewendet habe, wird ein Animationsobjekt auf seinen Ausgangszustand zurückgesetzt und anschließend aus diesem Zustand animiert. Was zusätzlich getan werden muss, ist, die gewünschte Eigenschaft der Modellebene gemäß der Eigenschaft der Präsentationsebene festzulegen, bevor eine neue Animation wie folgt festgelegt wird:
quelle
Die einfachste Lösung ist die Verwendung impliziter Animationen. Dies wird all diese Probleme für Sie lösen:
Wenn Sie z. B. die Dauer anpassen möchten, können Sie Folgendes verwenden
NSAnimationContext
:Hinweis: Dies wird nur unter macOS getestet.
Dabei habe ich zunächst keine Animation gesehen. Das Problem ist, dass die Ebene einer Ansichtssicherungsschicht keine Animation impliziert. Um dies zu lösen, stellen Sie sicher, dass Sie selbst eine Ebene hinzufügen (bevor Sie die Ansicht auf Ebenen-Backed setzen).
Ein Beispiel dafür wäre:
Die Verwendung
self.wantsLayer
machte keinen Unterschied in meinen Tests, aber es könnte einige Nebenwirkungen haben, die ich nicht kenne.quelle
Hier ist ein Beispiel vom Spielplatz:
false
zuisRemovedOnCompletion
- lassen Core Animation sauber , nachdem die Animation beendet istquelle