SwiftUI,@Published 和 ForEach 没有更新我的视图

Posted

技术标签:

【中文标题】SwiftUI,@Published 和 ForEach 没有更新我的视图【英文标题】:SwiftUI, @Published with ForEach not updating my View 【发布时间】:2021-03-05 17:47:20 【问题描述】:

我正在尝试制作产品列表。在 GetProducts 类中,我从 Firebase 数据库中获取数据。然后我使用@Published 在另一个结构中使用这个产品。但是在我的产品列表中,视图没有更新。

这里是简化的 GetProducts 类;

import Combine
import FirebaseDatabase

class GetProducts: ObservableObject 

private let database = Database.database().reference()

//Shared list
@Published var productList: [String] = []

//Reading the products from Firebase Database
func getProducts() 
    database.child("Products").child("Category1").child("name").observeSingleEvent(of: .value, with:  snapshot in
        guard let value = snapshot.value as? String else 
            return
        
        print("Value: \(value)")
        self.productList.append(value)
    )



在打印中一切似乎都很好,我得到了数据。和视图;

struct ProductsView: View 

@ObservedObject var products = GetProducts()

var body: some View 
    NavigationView 
        List 
            ForEach(0 ..< products.productList.count, id: \.self)  product in
                NavigationLink(destination: ProductDetails()) 
                    Text("\(products.productList[product])")
                
            
        
        .navigationBarTitle(Text("Product List"))
    


我在第一个视图 (ContentView) 中调用 getProducts 函数;

struct ContentView: View 

@ObservedObject var products = GetProducts()
@State var selected = 0

var body: some View 
    TabView(selection: $selected) 
        ProductsView()
            .tabItem 
                if self.selected == 0 
                    Image(systemName: "tray.and.arrow.down")
                    Text("Products")
                else 
                    Image(systemName: "tray.and.arrow.down.fill")
                    Text("Products")
                
            .tag(0)
        AddNewProductView()
            .tabItem 
                if self.selected == 1 
                    Image(systemName: "icloud.and.arrow.up")
                    Text("Add Product")
                else 
                    Image(systemName: "icloud.and.arrow.up.fill")
                    Text("Add Product")
                
            .tag(1)
    .onAppear(perform: products.getProducts)


【问题讨论】:

你在哪里调用getProducts()(函数,不是同名类型)? 在 ContentView 中。我现在编辑了问题@jnpdx 【参考方案1】:

您有两个不同的 GetProducts 实例,它们彼此不共享数据。不要在ProductsView 中创建一个新的,而是将其作为依赖项传递:

struct ProductsView: View 

@ObservedObject var products : GetProducts
AddNewProductView(products: products)

另外值得注意的是,您可能会在使用ForEach 的范围时遇到问题。我建议你切换到:

ForEach(products.productList, id: \.self)  product in
                NavigationLink(destination: ProductDetails()) 
                    Text("\(product)")
                
            

【讨论】:

以上是关于SwiftUI,@Published 和 ForEach 没有更新我的视图的主要内容,如果未能解决你的问题,请参考以下文章

SwiftUI:如何使用 UserDefaults 持久化 @Published 变量?

SwiftUI @Published 属性正在 DetailView 中更新

SwiftUI 和具有 @Published 的组合 Observable 对象不断发布

SwiftUI 如何将@Published 分配给另一个@Published

SwiftUI / Firebase:我可以使用@Published 向 Firebase 数据库发送和接收单个值吗?

SwiftUI - 更改 @Published 结构时是不是可以触发 didSet?