質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.46%
非同期処理

非同期処理とは一部のコードを別々のスレッドで実行させる手法です。アプリケーションのパフォーマンスを向上させる目的でこの手法を用います。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

Q&A

0回答

1763閲覧

[SwiftUI] animationを次々にズレなく実行したい

tennet

総合スコア0

非同期処理

非同期処理とは一部のコードを別々のスレッドで実行させる手法です。アプリケーションのパフォーマンスを向上させる目的でこの手法を用います。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

0グッド

0クリップ

投稿2021/10/29 03:04

編集2021/10/29 09:57

前提・実現したいこと

Swift(SwiftUI)で連続したアニメーションを表示したいです。
再生すると、最初は1つの時間間隔で1つのアニメーションが実行されるのですが、後半でアニメーションが実行されないと思えば、次の時間間隔で2つや3つ実行されたりします。
どのように記述すれば1つずつズレなくアニメーションが再生されるか教えていただきたいです。

発生している問題

まず、私が実現したいのは、Imageが上下左右に平行移動したり、回転したり、サイズが変わったりするアニメーションを次々に実行して、Imageを動かすところを見れるようにすることです。
Imageに対するモディファイアは以下の通りです。

Image(systemName: "hare") .font(.system(size: imageSize)) .position(x: self.currentPos.x, y: self.currentPos.y) .rotationEffect(Angle(degrees: deg))

 
最初にアニメーションをwhile文の中で以下のように順番に実行しようとしたところ、全ての処理が同時に再生されてしまいました。
(playは再生ボタンのオンオフを表すBool、Stepは何番目の処理か(0-index)、Listは上下左右など動きの型を決めた列挙体の配列、Timeは一つのアニメーションにかける時間)

while (play == true && Step < Len) { if List[Step] == .Right { withAnimation(Animation.linear(duration: Time)) { currentPos.x += 80 } } if List[Step] == .Turn { withAnimation(Animation.linear(duration: Time)) { deg += 90 } } if List[Step] == .SizeUp { withAnimation(Animation.linear(duration: Time)) { imageSize += 30 } } Step += 1 }

そこで、次はDispatchQueue.main.asyncAfterを使って、各処理の開始時間を遅らせました。
n番目の処理はTime*nの分遅らせることで、次々に処理していく形です。

while (play == true && Step < Len) { if List[Step] == .Right { DispatchQueue.main.asyncAfter(deadline: .now() + (Time * Double(Step))) { withAnimation(Animation.linear(duration: Time)) { currentPos.x += 80 } } } if List[Step] == .Turn { DispatchQueue.main.asyncAfter(deadline: .now() + (Time * Double(Step))) { withAnimation(Animation.linear(duration: Time)) { deg += 90 } } } if List[Step] == .SizeUp { DispatchQueue.main.asyncAfter(deadline: .now() + (Time* Double(Step))) { withAnimation(Animation.linear(duration: Time)) { imageSize += 30 } } } Step += 1 }

しかしこの形で15~20回目の処理あたりから段々と、1回処理されずに次2回分まとめて動いたり、2回処理されずに次3回分まとめて動いたりしました。
再生間隔よりアニメーション1つにかける時間を短くする、また、アニメーションのdurationを指定せずに再生間隔だけ指定する、どちらの場合でも後半で上記のようなズレが生じました。

どのように記述すれば1つ1つ別々に処理されるのでしょうか。
DispatchQueueについてあまり理解しきれていないせいかもしれませんが、どなたか教えていただけると非常にありがたいです。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだ回答がついていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.46%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問