【SwiftUI】この世でいちばんわかりやすいビューのアニメーション


この投稿は何?

SwiftUIフレームワークでiOSアプリを開発する際に、ビューをアニメーションさせる方法について基本を解説します。

実行環境

macOS 11.4
Xcode 12.5.1
Swift 5.4

ハンズオン

以下は、アプリのメイン画面のコードです。

メインの画面
struct ContentView: View {
    var body: some View {
        VStack {
            Smiley()    // ニコちゃんマーク 
            Button {
                // ボタンタップ時の処理
            } label: {
                Text("rotate smiley 90°")
                    .font(.title)
            }
        }
    }
}

このメイン画面では、笑顔の絵文字の下に「タップできるボタン」を配置しています。

ビューを回転する

rotateEffect(_:)モディファイアは、指定した角度の分だけビューを回転します。

struct ContentView: View {
    var body: some View {
        VStack {
            Smiley()
                .rotationEffect(Angle(degrees: 90.0))    // 90度だけ回転する
            Button {
                // ボタンタップ時の処理
            } label: {
                Text("rotate smiley 90°")
                    .font(.title)
            }
        }
    }
}

rotateEffect(_:)モディファイアに指定する角度は、Angle型のインスタンスです。
ボタンをタップするごとに、90度ずつ回転するようにします。

struct ContentView: View {
    @State private var angle = 0.0    // State属性プロパティ

    var body: some View {
        VStack {
            Smiley()
                .rotationEffect(Angle(degrees: angle))
            Button {
                // 角度を90ずつ増分する
                angle += 90.0
            } label: {
                Text("rotate smiley 90°")
                    .font(.title)
            }
        }
    }
}

ボタンをタップするたびに、ニコちゃんマークが90度ずつ回転します。
ただし、アニメーションではなく、瞬時に表示が切り替わるだけです。

アニメーションを適用する

animation(_:)モディファイアを使って、「ビューに適用済みのモディファイア効果」をアニメーション化することができます。

struct ContentView: View {
    @State private var angle = 0.0

    var body: some View {
        VStack {
            Smiley()
                .rotationEffect(Angle(degrees: angle))
                .animation(.easeInOut(duration: 1.0))    // 回転をアニメーション
            Button {
                angle += 90.0
            } label: {
                Text("rotate smiley 90°")
                    .font(.title)
            }
        }
    }
}

animation(_:)モディファイアには、「どのようにアニメーションするか」を指定することができます。
ここでは、easeInOut(duration:)メソッドを指定して、「1秒間で滑らかに」アニメーションさせています。