"Push" Animation in Objective-C

8

Ich habe zwei Ansichten: A und B. A ist oben auf dem Bildschirm positioniert, B ist am unteren Bildschirmrand positioniert.

Wenn der Benutzer eine Schaltfläche drückt, animiert B aufwärts mit einer EaseInEaseOut-Bezier-Kurve, bis er y = 0 erreicht. Während B auf dem Weg zu seinem Ziel ist, sollte es A nach oben drücken, wenn es auf A trifft. Wenn B beim Übergang von unten nach oben eine bestimmte y-Koordinate (A's Ursprung + Höhe) passiert hat, sollte A bei B bleiben, so scheint es, dass B A nach oben drückt.

Was ich bisher versucht habe:

  • Registrieren Sie einen target + selector auf einen CADisplayLink, unmittelbar nachdem der Benutzer die Schaltfläche gedrückt hat. Fordern Sie in diesem Selektor die Y-Koordinate von B an, indem Sie auf seine presentationLayer zugreifen und die y-Koordinate von A entsprechend anpassen. Diese Methode erweist sich jedoch als nicht genau genug: Der Rahmen der Präsentationsebene befindet sich hinter der aktuellen Position von B auf dem Bildschirm (wahrscheinlich, weil PresentationLayer die Position der animierenden Ansicht für die aktuelle Zeit neu berechnet, die länger als 1 Frame dauert). . Wenn ich die Animationsdauer von B verlängere, funktioniert diese Methode einwandfrei.
  • Registrieren Sie einen target + selector auf einen CADisplayLink, unmittelbar nachdem der Benutzer die Schaltfläche gedrückt hat. Berechnen Sie in diesem Selektor die aktuelle y-Koordinate von B, indem Sie die Bezier-Gleichung für x = verstrichene Zeit / Animationsdauer (die die zurückgelegte Quotiententfernung / Gesamtstrecke zurückgeben soll) lösen. Ich habe Apples Open Source UnitBezier.h dafür verwendet ( Ссылка ). Die Ergebnisse sind jedoch nicht korrekt.

Irgendwelche Vorschläge, was ich als nächstes versuchen kann?

    
datwelk 12.03.2013, 16:16
quelle

3 Antworten

2

Sie haben gesagt, dass Sie versucht haben, die Technik "B animieren und Anzeigeverbindung verwenden, um A zu aktualisieren" anzuwenden, und dass dies dazu führte, dass "A" hinter "B" zurückblieb. Sie könnten theoretisch eine neue Ansicht "C" animieren und dann die Frames von B und A in der Anzeigeverbindung entsprechend anpassen, wodurch Verzögerungen (relativ zueinander) eliminiert werden sollten.

    
Rob 12.03.2013, 18:26
quelle
4

Zwei einfache Lösungen:

  1. Nur animationWithDuration verwenden: Sie können Ihre Animation in zwei verschachtelte Animationen aufteilen, indem Sie das Verschieben von "B" auf "A" beschleunigen und dann das Verschieben von "animieren" mit "easy out" animieren "B" und "A" den Rest des Weges. Der einzige Trick besteht darin, sicherzustellen, dass die beiden duration -Werte sinnvoll sind, damit sich die Geschwindigkeit der Animation nicht zu ändern scheint.

    %Vor%
  2. Sie können animateWithDuration mit der vollständigen Animation von "B" umgehen, aber dann CADisplayLink verwenden und presentationLayer verwenden, um B's aktuellen frame abzurufen und A's Rahmen entsprechend anzupassen:

    %Vor%

    Hier sind die Methoden zum Starten, Stoppen und Behandeln der Anzeigeverbindung wie folgt definiert:

    %Vor%
Rob 12.03.2013 17:13
quelle
0

Sie können followin algorythm versuchen:

1) Setzen Sie A und B in UIView (d. h. UIview * gropedView)

2) Ändern Sie B.y, bis es gleich A.y + A.height ist (so wird B rechts unter dem A sein)

3) Animiere gruppierteView

    
Roma 12.03.2013 19:22
quelle