So animieren Sie einen UIView und einen CALayer synchron

Um diese Frage zu veranschaulichen, habe ich ein sehr kleines Xcode-Projekt auf Github vorgestellt (zwei Klassen, 11 KB Download).Schauen Sie sich hier das Wesentliche an oder verwendenGit-Klon [email protected]: 93982af3b65d2151672e.git.

Bitte betrachten Sie das folgende Szenario. Eine benutzerdefinierte Ansicht von mir, genannt'Containeransicht'enthält zwei kleine Quadrate. In diesem Screenshot dargestellt:

Das blaue Quadrat ist ein 22x22 PunktUIView Beispiel und das rote Quadrat ist ein 22x22 ptCALayer Beispiel. Für diese Frage möchte ich, dass die beiden Quadrate in der unteren rechten Ecke der Außenansicht "haften", während ich den Rahmen dieser Außenansicht animiere.

Ich ändere den Rahmen der Containeransicht innerhalb vonUIViewKlassenmethodeanimateWithDuration:delay:options:animations:completion:, mit einem nicht standardmäßigen Beschleunigungsparameter vom TypUIViewAnimationCurveEaseOut.

[UIView animateWithDuration:1.0 delay:0 
                    options:UIViewAnimationCurveEaseOut 
                 animations:^{ _containerView.frame = randomFrame; } 
                 completion:nil];

Hinweis: Sowohl der blaue UIView-Frame als auch der rote CALayer-Frame werden überschriebensetFrame: Methode der Container-Ansicht, aber die Ergebnisse wären die gleichen gewesen, wenn ich die blauen UIView's eingestellt hätteautoresizingMask Eigentum an UIView flexible linke und obere Ränder.

In der resultierenden Animation haftet das blaue Quadrat genau so an der Ecke, wie ich es beabsichtigt habe, aber das rote Quadrat ignoriert sowohl das Timing als auch die Beschleunigung der Animation vollständig. Ich gehe davon aus, dass dies auf die implizite Animationsfunktion von Core Animation zurückzuführen ist, eine Funktion, die mir schon oft geholfen hat.

Hier einige Screenshots in der Animationssequenz, die die Asynchronität der beiden Quadrate veranschaulichen:

Weiter zur Frage:Gibt es eine Möglichkeit, die beiden Frame-Änderungen zu synchronisieren, sodass sich der rote CALayer und der blaue UIView mit derselben Animationsdauer und Beschleunigungskurve bewegen und aneinander haften, als wären sie eine Ansicht?

P.S. Natürlich kann das erforderliche visuelle Ergebnis des Zusammenklebens der beiden Quadrate auf eine beliebige Anzahl von Wegen erreicht werden, beispielsweise indem beide Schichten zu einer der beiden Schichten werdenCALayers oderUIViews, aber das Projekt, in dem sich das eigentliche Problem befindet, hat einen sehr berechtigten Grund dafür, dass der eine ein CALayer und der andere ein UIView ist.

Antworten auf die Frage(2)

Ihre Antwort auf die Frage