The cards in our system can now be created using our AddCardForm and adding a save button. For each card, we'll also setup the custom attribute properties that we specified in the Core Data model file. To save information such as Color, we'll be converting this into Data and persisting it as Core Data's Binary Data attribute.
By the end of this lesson, you will be able to render our cards with any color:
Go ahead and make the following changes:
struct AddCardForm: View { @Environment(\.presentationMode) var presentationMode @State private var name = "" @State private var cardNumber = "" @State private var limit = "" @State private var cardType = "Visa" @State private var month = 1 @State private var year = Calendar.current.component(.year, from: Date()) @State private var color = Color.blue let currentYear = Calendar.current.component(.year, from: Date()) var body: some View { NavigationView { Form { // ... } .navigationTitle("Add Credit Card") .navigationBarItems(leading: cancelButton, trailing: saveButton) } } private var saveButton: some View { Button(action: { let viewContext = PersistenceController.shared.container.viewContext let card = Card(context: viewContext) card.name = self.name card.number = self.cardNumber card.limit = Int32(self.limit) ?? 0 card.expMonth = Int16(self.month) card.expYear = Int16(self.year) card.timestamp = Date() card.color = UIColor(self.color).encode() card.type = cardType do { try viewContext.save() presentationMode.wrappedValue.dismiss() } catch { print("Failed to persist new card: \(error)") } }, label: { Text("Save") }) } private var cancelButton: some View { Button(action: { presentationMode.wrappedValue.dismiss() }, label: { Text("Cancel") }) }}
struct CreditCardView: View { let card: Card var body: some View { VStack(alignment: .leading, spacing: 16) { Text(card.name ?? "") .font(.system(size: 24, weight: .semibold)) HStack { let imageName = card.type?.lowercased() ?? "" Image(imageName) .resizable() .scaledToFit() .frame(height: 44) .clipped() Spacer() Text("Balance: $5,000") .font(.system(size: 18, weight: .semibold)) } Text(card.number ?? "") Text("Credit Limit: $\(card.limit)") HStack { Spacer() } } .foregroundColor(.white) .padding() .background(VStack { if let colorData = card.color, let uiColor = UIColor.color(data: colorData), let actualColor = Color(uiColor) { // iOS 14// LinearGradient(gradient: .init(stops: [// .init(color: actualColor.opacity(0.6), location: 0),// .init(color: actualColor, location: 1)// ]), startPoint: .top, endPoint: .bottom) LinearGradient(colors: [ actualColor.opacity(0.6), actualColor ], startPoint: .center, endPoint: .bottom) } else { Color.purple } }) ) .overlay(RoundedRectangle(cornerRadius: 8) .stroke(Color.black.opacity(0.5), lineWidth: 1) ) .cornerRadius(8) .shadow(radius: 5) .padding(.horizontal) .padding(.top, 8) } }