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())
运算符。
我正在开发一款卡路里追踪器应用程序。 在我的应用程序中,我可以打开一些产品的详细信息,设置数量并将产品添加到“购物车”。 稍后,我想从阵列中读取所有收集的数据,并向他们展示一个简短的概述。
但是这个视图不会在对数组进行更改后更新。 由于我使用 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
打开我的 AmountViewstruct 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())
运算符。