私はSwiftUIで比較的複雑なアニメーションに取り組んでおり、さまざまなアニメーションフェーズをチェーン化するための最良/最もエレガントな方法は何なのかと思っています。
最初にスケーリングする必要があるビューがあるとします。次に数秒待ってからフェードします(次に数秒待って最初からやり直す-無期限に)。
同じビュー/スタックで複数のwithAnimation()ブロックを使用しようとすると、それらは相互に干渉してアニメーションをめちゃくちゃにしてしまいます。
これまでに思いついた最高の方法は、初期ビューの.onAppear()修飾子でカスタム関数を呼び出し、その関数に、アニメーション間の各ステージにwithAnimation()ブロックを配置し、それらの間に遅延を設定することです。したがって、基本的には次のようになります。
func doAnimations() {
withAnimation(...)
DispatchQueue.main.asyncAfter(...)
withAnimation(...)
DispatchQueue.main.asyncAfter(...)
withAnimation(...)
...
}
最終的にはかなり長くなり、あまり「きれい」ではありません。これを行うにはより良い/より良い方法が必要だと私は確信していますが、これまでに試みたすべてが私が望む正確なフローを与えませんでした。
任意のアイデア/推奨事項/ヒントをいただければ幸いです。ありがとう!
他の応答で述べたように、SwiftUIでアニメーションをチェーンするメカニズムは現在ありませんが、必ずしも手動タイマーを使用する必要はありません。代わりに、連鎖アニメーションでdelay
関数を使用できます。
withAnimation(Animation.easeIn(duration: 1.23)) {
self.doSomethingFirst()
}
withAnimation(Animation.easeOut(duration: 4.56).delay(1.23)) {
self.thenDoSomethingElse()
}
withAnimation(Animation.default.delay(1.23 + 4.56)) {
self.andThenDoAThirdThing()
}
これにより、DispatchQueue
またはTimer
を使用するよりも一貫してスムーズなチェーンアニメーションが生成されることがわかりました。おそらく、すべてのアニメーションに同じスケジューラを使用しているためです。
すべての遅延と継続時間を調整するのは面倒な場合があるため、意欲的な開発者は、計算をいくつかのグローバルwithChainedAnimation
関数に抽象化して処理するのではなく、.
タイマーの使用は機能します。これは私自身のプロジェクトから:
@State private var isShowing = true
@State private var timer: Timer?
...
func askQuestion() {
withAnimation(Animation.easeInOut(duration: 1).delay(0.5)) {
isShowing.toggle()
}
timer = Timer.scheduledTimer(withTimeInterval: 1.6, repeats: false) { _ in
withAnimation(.easeInOut(duration: 1)) {
self.isShowing.toggle()
}
self.timer?.invalidate()
}
// code here executes before the timer is triggered.
}
残念ながら、当分の間、キーフレームなどのサポートはありません。少なくとも彼らはonAnimationEnd()
...を追加できたかもしれませんが、そのようなことはありません。
運が良かったのは、シェイプパスのアニメーションです。キーフレームはありませんが、「AnimatableData」を定義できるため、より細かく制御できます。例として、別の質問に対する私の回答を確認してください: https://stackoverflow.com/a/56885066/7786555
その場合、回転するのは基本的には弧ですが、ゼロからある程度の長さまで成長し、ターンの終了時に徐々にゼロの長さに戻ります。アニメーションには3つのフェーズがあります。最初は、弧の一方の端が動きますが、もう一方は動きません。次に、両方が同じ速度で移動し、最後に2番目の端が最初の端に到達します。私の最初のアプローチはDispatchQueueのアイデアを使用することでしたが、うまくいきましたが、私は同意します。それはひどく醜いです。次に、AnimatableDataを適切に使用する方法を理解します。だから...パスをアニメーション化している場合、あなたは運がいいです。それ以外の場合は、よりエレガントなコードの可能性を待つ必要があるようです。