SwiftUI iOS 14 视图未使用@EnvironmentObject 更新@Published 数组

SwiftUI iOS 14 View does not Update @Published Array with @EnvironmentObject

我正在开发一款卡路里追踪器应用程序。 在我的应用程序中,我可以打开一些产品的详细信息,设置数量并将产品添加到“购物车”。 稍后,我想从阵列中读取所有收集的数据,并向他们展示一个简短的概述。

但是这个视图不会在对数组进行更改后更新。 由于我使用 userDefaults 存储数据,所以我总是必须重新打开应用程序才能更新视图。只有这样,孔阵列才会显示出来。

我的 Class 购物车:

import Foundation

struct Order: Equatable, Identifiable, Codable {
    var id = UUID()
    var product: Product
    var modifier: Double
    var date: Date
}


class Cart: ObservableObject {
    
    @Published var orders = [Order]()
    
    static let saveKey = "SavedData"
    
    init() {
        
        if let data = UserDefaults.standard.data(forKey: Self.saveKey) {
            if let decoded = try? JSONDecoder().decode([Order].self, from: data) {
                self.orders = decoded
            }
        } else {
            self.orders = []
        }
    }
    
    // save order
    func save() {
        if let encoded = try? JSONEncoder().encode(self.orders) {
            UserDefaults.standard.set(encoded, forKey: Self.saveKey)
        }
    }
    
    // add to order
    func add(order: Order) {
        self.orders.append(order)
        print("product added to cart")
        save()
    }
    
    // remove from order
    func remove(order: Order) {
        if let index = orders.firstIndex(of: order) {
            orders.remove(at: index)
        }
    }
    
}

我做了一个View申请任何特殊产品的金额。

import SwiftUI

struct AmountView: View {
    
    @EnvironmentObject var cart: Cart
    
    @State private var textInput = ""
    @State private var orderFinished = false
    var product: Product
        
    func StringDoubleConverter(text: String) -> String {
            return String(format: "%.2f", Double(textInput.replacingOccurrences(of: ",", with: ".")) ?? 0)
        }
    
    var body: some View {
        VStack {
            Form {
                Section(header: Text("Mengenangabe")) {
                    
                    // input for the amount
                    AmountInputView(textInput: $textInput)
                    if !orderFinished {
                        Button("Hinzufügen", action: {
                            orderFinished = true
                            
                            hideKeyboard()
        
                            // add product to the cart
                            self.cart.add(order: Order(product: product, modifier: Double(StringDoubleConverter(text: textInput))!, date: Date()))

                            
                        })
                        .disabled(textInput == "")
                        .animation(.default)
                    } else {
                        Text("Wurde zum Logbuch hinzugefügt")
                            .foregroundColor(.blue)
                    }
                }
                productNutritionCollectionView(product: product, modifier: Double(StringDoubleConverter(text: textInput))!)

            }
        }
    }
}

struct AmountView_Previews: PreviewProvider {
    
    static var previews: some View {
        AmountView(product: Product.exampleProduct).environmentObject(Cart())
    }
}

然后,我想使用 Form 和 ForEach lope 在日志视图中显示订单中的所有产品。

struct LogbookView: View {
    
    func deleteProducts(at offsets: IndexSet) {
        cart.orders.remove(atOffsets: offsets)
        cart.save()
    }
    
    @EnvironmentObject var cart: Cart
    
    @State private var date = Date()
    
    var body: some View {
        NavigationView {
            Form {
                Section(header: Text("List")) {
                    ForEach(cart.orders) { order in
                        Text(order.product.name)
                    }
                    .onDelete(perform: { indexSet in
                        deleteProducts(at: indexSet)
                    })
                    
                }
            }
            .navigationBarTitle(Text("Logbuch"), displayMode: .automatic)
            .navigationBarItems(trailing: DateView(date: $date))
        }
    }
}

struct LogbookView_Previews: PreviewProvider {
    
    
    static var previews: some View {
        LogbookView().environmentObject(Cart())
    }
}

我正在使用 AppTab 视图来浏览应用程序。因此,我将主结构中的 AppTab View 更改为具有 Cart 环境对象的默认 View。

@main
struct KalorientrackerApp: App {
    
    var body: some Scene {
        
        WindowGroup {
            AppTabView().environmentObject(Cart())
        }
    }
}

struct KalorientrackerApp_Previews: PreviewProvider {
    static var previews: some View {
        Text("Hello, World!")
    }
}

我正在使用 .sheet

打开我的 AmountView
struct ProductDetailView: View {
    
    @State private var showAmountView = false
    let product: Product
    
    var body: some View {
        VStack {
            // placeholder Image
            Image(product.fullImage)
                .clipShape(Circle())
                .padding(.top, 5)
            Spacer()
            
            Form {
                productNutritionCollectionView(product: product, modifier: 100)
            }
        }
        
        // Titel for Navigation bar
        .navigationBarTitle(Text(product.name), displayMode: .inline)
        
        // Button to go to amount view
        .navigationBarItems(trailing: Button(action: {
            self.showAmountView = true
        }, label: {
            Image(systemName: "plus.circle")
                .padding(.leading, 20)
        }).sheet(isPresented: $showAmountView, content: {
            
            AmountView(product: product).environmentObject(Cart())
        }))
    }
}

struct ProductDetailView_Previews: PreviewProvider {
    static var previews: some View {
        ProductDetailView(product: Product.exampleProduct)    }
}

我已经找到了一些其他讨论,但它们对我不起作用。

我正在使用 Xcode 12 beta 6 和 iOS14 beta 6

我自己发现了这个错误。问题是,我在 .sheet 操作中明确提交了一个 .environmentObject。

AmountView(product: product).environmentObject(Cart())

我从 .sheet 操作中删除了 .environmentObject(Cart())。现在可以使用了。

认为这是导致错误的原因,因为我在项目的主视图中使用了 .environmentObject(Cart()) 运算符。