【SwiftUI】動くメンバーシップカードを作成する

# はじめに
昨日、せっかくGlassmorphismのカードのようなUIを作成したのでもっとカードっぽくしていきたいと思います！

https://qiita.com/SNQ-2001/items/04502ac58b196743bad9

# サンプルアプリ
ドラッグでカードを動かすことができるようにしました。
![Simulator Screen Recording - iPhone 14 - 2022-12-18 at 17.49.02.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/b267677c-b14e-0ef8-7f2d-e875b4351870.gif)

# 実装
### View
```swift
import SwiftUI

struct ContentView: View {
    @State var x: CGFloat = 0
    @State var y: CGFloat = 0
    @State var isSheet: Bool = false
    @State var card: Card = .init(
        name: "山田太郎",
        number: "2567 6534 4512 1345",
        expire: "2027/04/13"
    )
    var body: some View {
        ZStack {
            Image("background")
                .resizable()
                .scaledToFill()
                .edgesIgnoringSafeArea(.all)
            VStack {
                Button {
                    isSheet = true
                } label: {
                    cardView
                }
                .buttonStyle(.glassmorphism)
                .rotation3DEffect(Angle(degrees: 5), axis: (x: x, y: y, z: 0))
                .animation(.default, value: 10)
                Spacer()
            }
        }
        .gesture(gesture)
        .sheet(isPresented: $isSheet) {
            cardInfoList
        }
    }

    private var cardView: some View {
        VStack(spacing: 10) {
            Text("Memberships Card")
                .foregroundColor(.white)
                .font(.system(size: 17, weight: .ultraLight, design: .rounded))
                .frame(maxWidth: .infinity, alignment: .leading)
                .padding(.all, 20)
            Spacer()
            Text(card.number)
                .foregroundColor(.white)
                .font(.system(size: 23, weight: .medium, design: .monospaced))
                .frame(maxWidth: .infinity, alignment: .center)
            Spacer()
            Text(card.expire)
                .foregroundColor(.white)
                .font(.system(size: 15, weight: .ultraLight, design: .rounded))
                .frame(maxWidth: .infinity, alignment: .trailing)
                .padding(.all, 20)
        }
        .frame(width: 320, height: 190)
    }

    private var cardInfoList: some View {
        List {
            LabeledContent {
                Text(card.name)
            } label: {
                Text("名前")
            }
            LabeledContent {
                Text(card.number)
            } label: {
                Text("番号")
            }
            LabeledContent {
                Text(card.expire)
            } label: {
                Text("有効期限")
            }
        }
        .listStyle(.insetGrouped)
        .presentationDetents([.medium])
    }

    private var gesture: _EndedGesture<_ChangedGesture<DragGesture>> {
        DragGesture()
            .onChanged { value in
                self.x = value.startLocation.y - value.location.y
                self.y = value.startLocation.x - value.location.x
            }
            .onEnded { _ in
                self.x = 0
                self.y = 0
            }
    }
}
```

### Model
```swift
struct Card {
    let name: String
    let number: String
    let expire: String
}
```

# おわり
カードっぽくなりました！！
でもカードのデザインが、、、、笑

Date扱うのめんどくさくて有効期限をStringにしたのは許してください