0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

SwiftUIで魅力的なショッピングカート追加アニメーションを実装する方法

Posted at

はじめに

SwiftUIでアニメーションを実装する練習として、今回は「ショッピングカートにアイテムを追加するアニメーション」を例に取り上げます。

環境

  • Xcode 16.1
  • Swift 6.0.2

アニメーションのイメージ

ユーザーが「Add to Cart」ボタンをタップすると、アイテム(CircleのView)がアニメーションでカートに追加される動きを再現します。アニメーションの要点は、アイテムがボタンからカートへスムーズに移動することです。

simulator.gif

実装のポイント

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. まとめ

  • 座標取得
    GeometryReaderPreferenceKeyを使用して、Viewの座標を取得します

  • SafeAreaの考慮
    取得した座標を基にSafeAreaを調整し、アニメーションの位置がずれないようにします

サンプルコード

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?