はじめに
SwiftUIでアニメーションを実装する練習として、今回は「ショッピングカートにアイテムを追加するアニメーション」を例に取り上げます。
環境
- Xcode 16.1
- Swift 6.0.2
アニメーションのイメージ
ユーザーが「Add to Cart」ボタンをタップすると、アイテム(CircleのView)がアニメーションでカートに追加される動きを再現します。アニメーションの要点は、アイテムがボタンからカートへスムーズに移動することです。
実装のポイント
1. 座標を取得する
まず、アニメーションを実現するために、アイテムを配置する位置(座標)を正確に把握する必要があります。下記の記事を参考に、idを指定して座標を取得できるようにします。
struct CoordinatePreferenceKey: PreferenceKey {
static var defaultValue: [UUID: CGRect] = [:]
static func reduce(value: inout [UUID: CGRect], nextValue: () -> [UUID: CGRect]) {
value.merge(nextValue(), uniquingKeysWith: { $1 })
}
}
struct CoordinateModifier: ViewModifier {
let id: UUID
func body(content: Content) -> some View {
content
.background(
GeometryReader { proxy in
Color.clear.preference(
key: CoordinatePreferenceKey.self,
value: [id: proxy.frame(in: .global)]
)
}
)
}
}
extension View {
func reportCoordinates(using id: UUID) -> some View {
self.modifier(CoordinateModifier(id: id))
}
}
このコードでは、GeometryReader
を使用してビューのCGRect
を取得し、それをPreferenceKey
に保持します。呼び出す時はreportCoordinates
を使って座標を取得できます。
2. 移動アニメーションの調整
取得した座標を基にアニメーションを実装します。しかし、このままだとSafeAreaが含まれた値になってしまい、位置がずれてしまいます。下記の記事を参考に、SafeAreaの値を取得しました。
window
のSafeAreaを取得し、アニメーションの座標計算時にSafeAreaのtopを引いて調整しました。
3. まとめ
-
座標取得
GeometryReader
とPreferenceKey
を使用して、Viewの座標を取得します -
SafeAreaの考慮
取得した座標を基にSafeAreaを調整し、アニメーションの位置がずれないようにします
サンプルコード