This is yet another expansion of my TextField and function questions.
The code for my Lunch Card app is pretty much set in stone, except for a little bug with a variable. This bug happens when you create a new card. Here's the code for both CardsView and AddView.
CardView:
AddView:
AddView shows as a sheet.
When looking, you can see that cardsInfo.newCard is being used to signify - if not obvious - a new card. But, the bug here is that when you add multiple cards, the previous cards are being overridden.
A solution I'm thinking of is adding the already-added cards into some kind of database or text file, but (1) I have literally no idea how I would approach that, and (2) that would probably mean rewriting about 3/4 of the existing code, which is a path that I am trying to avoid.
The code for my Lunch Card app is pretty much set in stone, except for a little bug with a variable. This bug happens when you create a new card. Here's the code for both CardsView and AddView.
CardView:
Code Block // // CardsView.swift // Lunch Card (iOS) // // Created by Joshua Srery on 12/17/20. // Additional code by OOPer on Apple Developer Forums // import SwiftUI struct Card: Identifiable { let id = UUID() let title: String } struct CardsView: View { @StateObject var cardsInfo = CardsInfo() @StateObject var sheetInfo = SheetInfo() @State private var editMode = EditMode.inactive var body: some View { NavigationView { List { ForEach(cardsInfo.cards) { cards in NavigationLink(destination: CardFullView(cname: cardsInfo.newCard.cname, name: cardsInfo.newCard.name, id: cardsInfo.newCard.id)) { CardRow(cname: cardsInfo.newCard.cname, name: cardsInfo.newCard.name, id: cardsInfo.newCard.id) } } .onDelete(perform: onDelete) .onMove(perform: onMove) }.listStyle(PlainListStyle()) .navigationTitle("Cards") .toolbar { ToolbarItem(placement: .navigationBarLeading) { EditButton() } ToolbarItem(placement: .navigationBarTrailing) { Button(action: { self.sheetInfo.showSheetView.toggle() }) { Image(systemName: "plus") } } } .environment(\.editMode, $editMode) .sheet(isPresented: $sheetInfo.showSheetView) { AddView(cardsInfo: cardsInfo, sheetInfo: sheetInfo) } } } private func onDelete(offsets: IndexSet) { cardsInfo.cards.remove(atOffsets: offsets) } private func onMove(source: IndexSet, destination: Int) { cardsInfo.cards.move(fromOffsets: source, toOffset: destination) } }
AddView:
Code Block // // AddView.swift // Lunch Card (iOS) // // Created by Joshua Srery on 12/18/20. // Additional code by OOPer on Apple Developer Forums // import SwiftUI struct AddView: View { @ObservedObject var cardsInfo: CardsInfo @ObservedObject var sheetInfo: SheetInfo var body: some View { NavigationView { VStack { CardView(name: cardsInfo.newCard.name, id: cardsInfo.newCard.id) TextField("Name", text: $cardsInfo.newCard.name) .textFieldStyle(RoundedBorderTextFieldStyle()) .shadow(radius: 10) TextField("ID", text: $cardsInfo.newCard.id) .textFieldStyle(RoundedBorderTextFieldStyle()) .keyboardType(.numberPad) .shadow(radius: 10) TextField("Card Name", text: $cardsInfo.newCard.cname) .textFieldStyle(RoundedBorderTextFieldStyle()) .shadow(radius: 10) Button(action: { cardsInfo.add() sheetInfo.showSheetView = false }) { Text("Create") .bold() } .disabled(self.cardsInfo.newCard.name.isEmpty self.cardsInfo.newCard.id.isEmpty self.cardsInfo.newCard.cname.isEmpty) .foregroundColor(.white) .padding() .padding(.horizontal, 100) .background(Color.accentColor) .cornerRadius(10) }.padding() .navigationTitle(cardsInfo.newCard.cname) .navigationBarTitleDisplayMode(.inline) } } }
AddView shows as a sheet.
When looking, you can see that cardsInfo.newCard is being used to signify - if not obvious - a new card. But, the bug here is that when you add multiple cards, the previous cards are being overridden.
A solution I'm thinking of is adding the already-added cards into some kind of database or text file, but (1) I have literally no idea how I would approach that, and (2) that would probably mean rewriting about 3/4 of the existing code, which is a path that I am trying to avoid.
The word override can be interpreted in several ways, so I may be mistaking something, but your problem seems to be caused by your List in CardsView.
You use ForEach for cardsInfo.cards, receiving each card in card. But your CardRow always shows cardsInfo.newCard ignoring each card.
So, every row in your List shows always the only CardInfo kept in cardsInfo.newCard.
You may need to have an Array of CardInfo in your CardsInfo, and show it in your CardsView:
If this change causes something wrong, please try to explain that showing --
Code Block NavigationLink(destination: CardFullView(cname: cardsInfo.newCard.cname, name: cardsInfo.newCard.name, id: cardsInfo.newCard.id)) { CardRow(cname: cardsInfo.newCard.cname, name: cardsInfo.newCard.name, id: cardsInfo.newCard.id) }
You use ForEach for cardsInfo.cards, receiving each card in card. But your CardRow always shows cardsInfo.newCard ignoring each card.
So, every row in your List shows always the only CardInfo kept in cardsInfo.newCard.
You may need to have an Array of CardInfo in your CardsInfo, and show it in your CardsView:
CardsInfo
Code Block struct CardInfo: Identifiable { //<- Needs `Identifiable` to use with `ForEach` var name: String = "" var id: String = "" var cname: String = "" } class CardsInfo: ObservableObject { @Published var newCard: CardInfo = CardInfo() @Published var cards: [CardInfo] = [] //<- Make this an Array of `CardInfo`, not of `Card` func add() { cards.append(newCard) //<- Add `newCard` to `cards` } }
CardsView:
Code Block var body: some View { NavigationView { List { Text("\(sheetInfo.showSheetView.description)") ForEach(cardsInfo.cards) { card in NavigationLink(destination: CardFullView(cname: card.cname, name: card.name, id: card.id)) { //<- CardRow(cname: card.cname, name: card.name, id: card.id) //<- } } .onDelete(perform: onDelete) .onMove(perform: onMove) } //... } }
If this change causes something wrong, please try to explain that showing --
Steps to reproduce
What you expect
What you actually get