'SwiftUI List not updating after deleting row from Sqlite DB
I have a list of objects that a user can click on to navigate to a detailed view and then delete. This works fine but when I added a .swipeActions() to the cardListRow I get an index out of bounds error after deleting.
Initial View:
struct ContentView: View {
//variables for Ingredient list:
@State var ingredients: [Ingredient] = []
var body: some View {
NavigationView{
ScrollView{
VStack{
//Ingredient Section
VStack{
List{
ForEach(self.$ingredients, id: \.id){ ingredientModel in
//print each ingredient
CardListRow(item: ingredientModel)
.listRowSeparator(.hidden)
}
}
.frame(height: 180)
.listStyle(.plain)
.onAppear(perform: {
print("Load ingredients from DB")
self.ingredients = Ingredient_DB().getIngredients()
})
}
}
}
}
}
CardListRow:
struct CardListRow: View {
@Binding var item: Ingredient
@State var inStock: Bool = false
@State var showingAlert: Bool = false
var body: some View {
ZStack {
Color.white
.cornerRadius(12)
IngredientListItem(ingredient: $item)
}
.fixedSize(horizontal: false, vertical: true)
.shadow(color: Color.black.opacity(0.2), radius: 3, x: 0, y: 2)
.swipeActions() {
if self.inStock == true {
Button (action: {
self.inStock = false
item.inStock = self.inStock
Ingredient_DB().updateIngredient(idValue: self.item.id.uuidString, nameValue: self.item.name, inStockValue: self.item.inStock)
}) {
Text("Out of stock")
}
.tint(.yellow)
}else{
Button (action: {
self.inStock = true
item.inStock = self.inStock
Ingredient_DB().updateIngredient(idValue: self.self.item.id.uuidString, nameValue: self.item.name, inStockValue: self.item.inStock)
}) {
Text("In stock")
}
.tint(.green)
}
}
.onAppear(perform: {
self.inStock = item.inStock //Error occurs here. List isn't reloaded but item is out of index
})
}
}
IngredientListItem:
struct IngredientListItem: View {
//ingredient to display
@Binding var ingredient: Ingredient
//to see if ingredient was clicked on
@State var ingredientSelected: Bool = false
var body: some View {
//navigation link to view ingredient info
NavigationLink (destination: ViewIngredientView(ingredient: $ingredient), isActive: self.$ingredientSelected){
EmptyView()
}
HStack {
if !ingredient.inStock{
Image(systemName: "x.square")
.foregroundColor(.red)
.padding(.leading, 5)
}
Text(ingredient.name)
.font(.body)
.padding(.leading, 5)
.frame(minWidth: 100)
Divider()
.frame(width: 10)
Spacer()
}
.padding(.top, 3)
.padding(.bottom, 3)
}
}
ViewIngredientView:
struct ViewIngredientView: View {
//Name of recipe received from previous view
@Binding var ingredient: Ingredient
//To return to previous view
@Environment(\.presentationMode) var mode: Binding<PresentationMode>
var body: some View {
VStack {
Text(ingredient.name)
.font(.title)
.padding(.leading, 5)
}
.navigationBarItems(trailing:
HStack{
Spacer()
//Delete Button
Button("Delete") {
//Remove recipe from Recipe_DB
Ingredient_DB().deleteIngredient(ingredientID: ingredient.id.uuidString)
//Remove recipe from Recipe_Ingredient_DB
Recipe_Ingredient_DB().deleteIngredient(ingredientIDValue: ingredient.id.uuidString)
//return to previous screen
self.mode.wrappedValue.dismiss()
}
.padding()
})
}
}
Ingredient:
import Foundation
class Ingredient: Identifiable, Hashable{
static func == (lhs: Ingredient, rhs: Ingredient) -> Bool {
if (lhs.id == rhs.id) {return true}
else {return false}
}
func hash(into hasher: inout Hasher) {
hasher.combine(id)
}
public var id = UUID()
public var name: String = ""
public var inStock: Bool = false
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
