本記事ではSwiftUIで使えるアニメーション効果の種類について解説します。
アニメーション効果はAnimation構造体で定義します。
環境
この記事の情報は次のバージョンで動作確認しています。
【Swift】5.2.4
【iOS】13.5
【macOS】Catalina バージョン 10.15.4
基本的な使い方
Viewに対して次のModifierを付加すると、形状やエフェクトの変更が自動的にアニメーション化されます。
1 2 3 |
.animation(Animation) |
.animationモディファイアの基本的な使い方については、別の記事【SwiftUI】アニメーションの基本を参照して下さい。
引数に渡すAnimation構造体のインスタンスによって、アニメーションのタイプを決定します。
基本的なアニメーションを示すインスタンスは、次のタイププロパティで生成します。
タイププロパティ | 解説 |
---|---|
Animation.default | デフォルトアニメーション。設定するViewによって動きが異なります。 |
Animation.easeInOut | 開始は遅く、中盤は速く、終盤は再び遅くなります。 |
Animation.easeIn | 開始は遅く、徐々に速くなります。 |
Animation.easeOut | 開始は速く、徐々に遅くなります。 |
Animation.linear | 開始から終了まで等速です。 |
使用例
表示切り替えフラグ(flag)が切り替わると、背景色、表示サイズ、回転角度、表示位置が変化するテキストパネルのサンプルです。
「アニメーション」をタップすると、全ての変化が同時にアニメーション化されます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
struct ContentView: View { @State private var flag = false // 表示の切り替えフラグ var body: some View { ZStack { Text("カピ通信") .font(.largeTitle) .padding() .background(flag ? Color.green : Color.yellow) // 背景色 .scaleEffect(flag ? 2.0 : 1.0) // Viewの拡大 .rotationEffect(Angle(degrees: flag ? 360 : 0)) // Viewの回転 .offset(x: flag ? 100 : -100) // Viewの表示位置 /// アニメーション設定 .animation(.default) VStack { Spacer() Button("アニメーション") { self.flag.toggle() } } } } } |
動作時間の指定
上記で紹介したタイププロパティについて、.default以外は次のタイプメソッドへの置き換えで、アニメーションの動作時間を指定できます。
引数(duration)には秒数を指定します。
1 2 3 4 5 6 7 8 9 |
Animation.easeInOut(duration: Double) Animation.easeIn(duration: Double) Animation.easeOut(duration: Double) Animation.linear(duration: Double) |
前章の使用例のアニメーション設定の部分を次のように置き換えると、3秒かけてゆっくりとテキストパネルが移動します。
1 2 3 4 |
/// アニメーション設定 .animation(.easeInOut(duration: 3.0)) |
ばねのアニメーション
目的のポイントに移動し、少し行き過ぎてから跳ね返る、ばねのような動きのアニメーションです。
SwiftUIでは計算式の異なる2種類のばねアニメーションが用意されています。
単振動モデル
単振動モデルで動く、ばねアニメーションを生成します。
下記に示す2つのメソッドがありますが、引数のデフォルト値が異なるだけで、動きは同じです。
1 2 3 4 5 6 7 8 9 10 11 |
Animation.spring( response: Double = 0.55, dampingFraction: Double = 0.825, blendDuration: Double = 0) Animation.interactiveSpring( response: Double = 0.15, dampingFraction: Double = 0.86, blendDuration: Double = 0.25) |
引数を指定せずにデフォルト値で使った時に、
・spring()は動作の終了時点で、わずかにばねのような跳ね返りが発生します。
・interactiveSpring()は標準より反応が早い動きとなり、ボタンをタップするなどインタラクティブな操作での使用を想定しています。
引数の説明は下記の通りです。
response
反応速度を示します。値が小さいほど速くなります。
damping Fraction
ばねの動きを押し止める度合いです。
この値を小さくするとばねのうごきが止まりにくくなって、よりびょんびょん動くイメージです。0にすると永久に動き続けます。
1より大きい場合は全く跳ね返りをしませんので、通常は0から1の値を選択します。
blendDuration
ばねアニメーションが動作している最中のViewを、別のばねアニメーションに移行させた場合、初めのアニメーションの運動を初速として次の運動に引き渡します。この切り替わる時の前後の運動合成時間を指定します。
減衰振動モデル
減衰振動モデルで動く、ばねアニメーションを生成します。
1 2 3 4 5 6 7 |
interpolatingSpring( mass: Double = 1.0, stiffness: Double, damping: Double, initialVelocity: Double = 0.0) |
引数の説明は下記の通りです。
mass
ばねに掛かる質量を指定します。
stiffness(必須)
ばねの剛性を指定します。
大きいほどばねが固くなります。
damping(必須)
減衰係数を指定します。
小さいほど止まりにくくなります。
initialVelocity
ばねの初期速度を指定します。
使用例
各ばねアニメーションと標準アニメーションの比較をするサンプルです。
引数を変えて動きを確認してみると良いでしょう。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
struct ContentView: View { @State private var flag = false // 表示の切り替えフラグ var body: some View { ZStack { VStack(spacing: 50) { Text("default") .frame(width: 300, height: 30) .background(Color.blue) .rotationEffect(Angle(degrees: flag ? 180 : 0)) // Viewの回転 .animation(.default) Text("spring") .frame(width: 300, height: 30) .background(Color.green) .rotationEffect(Angle(degrees: flag ? 180 : 0)) // Viewの回転 .animation(.spring()) Text("interactiveSpring") .frame(width: 300, height: 30) .background(Color.red) .rotationEffect(Angle(degrees: flag ? 180 : 0)) // Viewの回転 .animation(.interactiveSpring()) Text("interpolatingSpring") .frame(width: 300, height: 30) .background(Color.yellow) .rotationEffect(Angle(degrees: flag ? 180 : 0)) // Viewの回転 .animation(.interpolatingSpring(stiffness: 50, damping: 5)) } VStack { Spacer() Button("アニメーション") { self.flag.toggle() } } } } } |
その他オプション
Animation構造体で使えるその他のオプションを紹介します。
本記事の上記方法で生成したAnimationインスタンスのインスタンスメソッドしてして使用します。
開始を遅らせる(delay)
1 2 3 |
delay(Double) |
アニメーションを開始する前に待機する秒数を引数で指定します。
下で紹介する繰り返し処理と併用した場合、繰り返しのたびに待機が発生します。
回数指定の繰り返し(repeatCount)
1 2 3 |
repeatCount(Int, autoreverses: Bool = true) |
アニメーションを繰り返す回数を最初の引数で指定します。
2番目の引数(autoreverses)は、初期状態に戻るプロセスもアニメーション化するかどうかを決定します。
初期状態に戻るプロセスも回数としてカウントされますので、この場合、偶数回を指定すると初期状態に戻ったタイミングでアニメーションが終了し、そこから最終状態に瞬時に切り替わる若干不自然な動きとなります。
永久繰り返し(repeatForever)
1 2 3 |
repeatForever(autoreverses: Bool = true) |
アニメーションを無制限に繰り返します。
引数(autoreverses)の用途は、repeatCountと同様です。
速度指定(speed)
1 2 3 |
speed(Double) |
アニメーションの実行速度を倍率で指定します。
標準は1.0で、数字が大きくなる程速く、小さいほど遅くなります。
例として0.25を指定した場合は、通常の4倍の時間がかかります。
使用例
「アニメーション」をタップすると、バウンドしながら青丸のサイズが変化します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
struct ContentView: View { @State private var flag = false // 表示の切り替えフラグ var body: some View { ZStack { Circle() .fill(Color.blue) .frame(width: 150, height: 150) .scaleEffect(flag ? 1.2 : 1.0) // Viewの拡大 /// アニメーション設定 .animation(Animation.default // "Animation"は省略不可 .repeatCount(3) // 3回繰り返し .speed(2.0) // 2倍速で実行 ) VStack { Spacer() Button("アニメーション") { self.flag.toggle() } } } } } |
"Animation.default"の部分を".default"とするとエラーになるので注意して下さい。
インスタンスメソッドを使用する場合、インスタンス生成時の構造体名を省略できません。