【发布时间】:2020-08-30 19:13:40
【问题描述】:
我正在开发一个卡路里跟踪器应用程序。 在我的应用程序中,我可以打开一些产品的详细信息,设置数量并将产品添加到“购物车”。 稍后,我想从数组中读出所有收集到的数据,并给他们一个简短的概述。
但是在对数组进行更改后,此视图将不会更新。 由于我使用 userDefaults 存储数据,我总是必须重新打开应用程序来更新视图。只有这样,孔阵列才会显示出来。
我的课堂购物车:
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)
}
}
}
我做了一个视图来应用任何特殊产品的数量。
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 视图来导航应用程序。因此,我将主 Struct 中的 AppTab View 更改为默认 View,环境对象为 Cart。
@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
【问题讨论】:
-
您是否在 SceneDelegate 中添加了您的环境变量? window.rootViewController = UIHostingController(rootView: contentView.environmentObject(Cart())) 然后初始化你的 Cart 类加载 UserDefaults
-
SceneDelegate 在 Xcode12 中不再可用。这是一个在 Xcode 测试版中制作的新项目。我将购物车添加到 @main 结构中。
-
据我所知,您没有提供代码的问题部分。你会展示你创建购物车的部分,你如何列出订单,你如何创建工作表......还是我们应该猜测?
-
对不起。将缺失的代码添加到问题中。
-
我遇到了类似的问题。这篇文章为我解决了这个问题:stackoverflow.com/questions/57615920/…