LoginSignup
4
2

More than 1 year has passed since last update.

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

Posted at

はじめに

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

サンプルアプリ

ドラッグでカードを動かすことができるようにしました。
Simulator Screen Recording - iPhone 14 - 2022-12-18 at 17.49.02.gif

実装

View

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

struct Card {
    let name: String
    let number: String
    let expire: String
}

おわり

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

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

4
2
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
4
2