【SwiftUI】KeyframeAnimation使ってみた

# はじめに
iOS17から使えるKeyframeAnimationを調べならが使ってみたのでちょっとまとめたのを投稿しておきます。

# 最小単位のサンプル
```swift
import SwiftUI

//　`KeyframeAnimationValues`で指定した値を`keyframeAnimator`で使用できる
struct KeyframeAnimationValues {
    var scale = 1.0
}

struct ContentView: View {
    var body: some View {
        VStack {
            Image(systemName: "heart.fill")
                .resizable()
                .scaledToFit()
                .frame(width: 100)
                .foregroundStyle(.red)
                .keyframeAnimator(
                    initialValue: KeyframeAnimationValues()
                ) { content, value in
                    // `value`は`KeyframeAnimationValues`
                    content.scaleEffect(value.scale)
                } keyframes: { _ in
                    // `scale`を1秒間かけて0.5にする
                    KeyframeTrack(\.scale) {
                        CubicKeyframe(0.5, duration: 1)
                    }
                }
        }
    }
}
```

実行するとこうなる

![Simulator Screen Recording - iPhone 15 Pro - 2023-11-19 at 19.46.18.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/1f81f0c0-00ed-cee7-d93d-76b5bf2d6dd3.gif)

# 疑問
`KeyframeTrack`の中の`CubicKeyframe`は何？

答え → `KeyframeTrackContent`

# KeyframeTrackContentって何があるの？
以下の4種類があります。
- CubicKeyframe
- LinearKeyframe
- MoveKeyframe
- SpringKeyframe

### CubicKeyframe
3次曲線を使用して値間を滑らかに補間するキーフレーム。

https://developer.apple.com/documentation/swiftui/cubickeyframe

### LinearKeyframe
単純な線形補間を使用したキーフレーム。

https://developer.apple.com/documentation/swiftui/linearkeyframe

### MoveKeyframe
補間することなく、指定された値に即座に移動するキーフレーム。

https://developer.apple.com/documentation/swiftui/movekeyframe

### SpringKeyframe
スプリング関数を使用して、指定された値に補間するキーフレーム。

https://developer.apple.com/documentation/swiftui/springkeyframe

# 複数条件
複数条件を実行させて心臓の鼓動を完成させる
```swift
import SwiftUI

struct KeyframeAnimationValues {
    var scale = 1.0
    var opacity = 1.0
}

struct ContentView: View {
    var body: some View {
        Image(systemName: "heart.fill")
            .resizable()
            .scaledToFit()
            .frame(width: 100)
            .foregroundStyle(.red)
            .keyframeAnimator(
                initialValue: KeyframeAnimationValues()
            ) { content, value in
                content
                    .scaleEffect(value.scale)
                    .opacity(value.opacity)
            } keyframes: { _ in
                KeyframeTrack(\.scale) {
                    CubicKeyframe(0.8, duration: 0.3)
                    CubicKeyframe(0.6, duration: 0.3)
                    CubicKeyframe(1.0, duration: 0.3)
                }

                KeyframeTrack(\.opacity) {
                    CubicKeyframe(0.8, duration: 0.3)
                    CubicKeyframe(0.6, duration: 0.3)
                    CubicKeyframe(1.0, duration: 0.3)
                }
            }
    }
}
```

![Simulator Screen Recording - iPhone 15 Pro - 2023-11-19 at 22.22.53.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/d3b55a38-bf97-68e1-d0cb-44c01e740a04.gif)

# おわり
`KeyframeTrackContent`の各種動きの違いなどを調べたい
KeyframeAnimationに入門はできたので色々試して記事書いていく

# 参考記事
https://www.appcoda.com/keyframeanimator/